From c4d029f2479378cb263784330c4962c0d7867ef0 Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Mon, 9 May 2016 15:47:16 -0400 Subject: [PATCH 01/56] Bug 1052467 - reordering tps page list to avoid hang on winxp as winxp runs fewer pages. r=wlach MozReview-Commit-ID: 7UGgR52GSa4 --HG-- extra : rebase_source : 7df21ce6b64af7068da8e8e31b15ec771ba25a48 --- testing/talos/talos/tests/tp5o.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/talos/talos/tests/tp5o.html b/testing/talos/talos/tests/tp5o.html index 2223c1609aac..82ba15b4e90a 100644 --- a/testing/talos/talos/tests/tp5o.html +++ b/testing/talos/talos/tests/tp5o.html @@ -1,4 +1,3 @@ -link
link
link
link
@@ -48,4 +47,5 @@ link
link
link
+link
From 7b5fd55b61cfc6e5d3ee42993ce361cd075fcadc Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Tue, 10 May 2016 15:45:01 -0700 Subject: [PATCH 02/56] Bug 1269451 - Make the UncompressedSourceCache use the shared, immutable strings infrastructure; r=jimb --- js/src/jsfun.cpp | 7 +- js/src/jsscript.cpp | 172 +++++++++++++------------------------------- js/src/jsscript.h | 47 ++++-------- 3 files changed, 66 insertions(+), 160 deletions(-) diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index f56ef64c7c43..edf5d4650c78 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -1437,12 +1437,11 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext* cx, HandleFuncti MOZ_ASSERT(lazy->scriptSource()->hasSourceData()); // Parse and compile the script from source. - UncompressedSourceCache::AutoHoldEntry holder; - const char16_t* chars = lazy->scriptSource()->chars(cx, holder); - if (!chars) + auto text = lazy->scriptSource()->sourceText(cx); + if (!text) return false; - const char16_t* lazyStart = chars + lazy->begin(); + const char16_t* lazyStart = text->chars() + lazy->begin(); size_t lazyLength = lazy->end() - lazy->begin(); if (!frontend::CompileLazyFunction(cx, lazy, lazyStart, lazyLength)) { diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index b274e9f8b4b2..ec62710c357a 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1812,73 +1812,19 @@ JSScript::sourceData(JSContext* cx) return scriptSource()->substring(cx, sourceStart(), sourceEnd()); } -UncompressedSourceCache::AutoHoldEntry::AutoHoldEntry() - : cache_(nullptr), source_(nullptr) +mozilla::Maybe +UncompressedSourceCache::lookup(ScriptSource* ss) { -} - -void -UncompressedSourceCache::AutoHoldEntry::holdEntry(UncompressedSourceCache* cache, ScriptSource* source) -{ - // Initialise the holder for a specific cache and script source. This will - // hold on to the cached source chars in the event that the cache is purged. - MOZ_ASSERT(!cache_ && !source_ && !charsToFree_); - cache_ = cache; - source_ = source; -} - -void -UncompressedSourceCache::AutoHoldEntry::deferDelete(UniqueTwoByteChars chars) -{ - // Take ownership of source chars now the cache is being purged. Remove our - // reference to the ScriptSource which might soon be destroyed. - MOZ_ASSERT(cache_ && source_ && !charsToFree_); - cache_ = nullptr; - source_ = nullptr; - charsToFree_ = Move(chars); -} - -UncompressedSourceCache::AutoHoldEntry::~AutoHoldEntry() -{ - if (cache_) { - MOZ_ASSERT(source_); - cache_->releaseEntry(*this); - } -} - -void -UncompressedSourceCache::holdEntry(AutoHoldEntry& holder, ScriptSource* ss) -{ - MOZ_ASSERT(!holder_); - holder.holdEntry(this, ss); - holder_ = &holder; -} - -void -UncompressedSourceCache::releaseEntry(AutoHoldEntry& holder) -{ - MOZ_ASSERT(holder_ == &holder); - holder_ = nullptr; -} - -const char16_t* -UncompressedSourceCache::lookup(ScriptSource* ss, AutoHoldEntry& holder) -{ - MOZ_ASSERT(!holder_); if (!map_) - return nullptr; - if (Map::Ptr p = map_->lookup(ss)) { - holdEntry(holder, ss); - return p->value().get(); - } - return nullptr; + return mozilla::Nothing(); + if (Map::Ptr p = map_->lookup(ss)) + return mozilla::Some(p->value().clone()); + return mozilla::Nothing(); } bool -UncompressedSourceCache::put(ScriptSource* ss, UniqueTwoByteChars str, AutoHoldEntry& holder) +UncompressedSourceCache::put(ScriptSource* ss, SharedImmutableTwoByteString&& str) { - MOZ_ASSERT(!holder_); - if (!map_) { UniquePtr map = MakeUnique(); if (!map || !map->init()) @@ -1887,11 +1833,7 @@ UncompressedSourceCache::put(ScriptSource* ss, UniqueTwoByteChars str, AutoHoldE map_ = Move(map); } - if (!map_->put(ss, Move(str))) - return false; - - holdEntry(holder, ss); - return true; + return map_->put(ss, Move(str)); } void @@ -1900,13 +1842,6 @@ UncompressedSourceCache::purge() if (!map_) return; - for (Map::Range r = map_->all(); !r.empty(); r.popFront()) { - if (holder_ && r.front().key() == holder_->source()) { - holder_->deferDelete(Move(r.front().value())); - holder_ = nullptr; - } - } - map_.reset(); } @@ -1914,45 +1849,39 @@ size_t UncompressedSourceCache::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) { size_t n = 0; - if (map_ && !map_->empty()) { + if (map_ && !map_->empty()) n += map_->sizeOfIncludingThis(mallocSizeOf); - for (Map::Range r = map_->all(); !r.empty(); r.popFront()) - n += mallocSizeOf(r.front().value().get()); - } return n; } -const char16_t* -ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holder) +mozilla::Maybe +ScriptSource::sourceText(JSContext* cx) { - struct CharsMatcher + struct SourceTextMatcher { - using ReturnType = const char16_t*; + using ReturnType = mozilla::Maybe; JSContext* cx; ScriptSource& ss; - UncompressedSourceCache::AutoHoldEntry& holder; - explicit CharsMatcher(JSContext* cx, ScriptSource& ss, - UncompressedSourceCache::AutoHoldEntry& holder) + explicit SourceTextMatcher(JSContext* cx, ScriptSource& ss) : cx(cx) , ss(ss) - , holder(holder) { } ReturnType match(Uncompressed& u) { - return u.string.chars(); + return mozilla::Some(u.string.clone()); } ReturnType match(Compressed& c) { - if (const char16_t* decompressed = cx->runtime()->uncompressedSourceCache.lookup(&ss, holder)) - return decompressed; + if (auto decompressed = cx->runtime()->uncompressedSourceCache.lookup(&ss)) + return mozilla::Some(mozilla::Move(*decompressed)); const size_t lengthWithNull = ss.length() + 1; UniqueTwoByteChars decompressed(js_pod_malloc(lengthWithNull)); if (!decompressed) { - JS_ReportOutOfMemory(cx); - return nullptr; + ReportOutOfMemory(cx); + return mozilla::Nothing(); } if (!DecompressString((const unsigned char*) ss.compressedData(), @@ -1960,43 +1889,44 @@ ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holde reinterpret_cast(decompressed.get()), lengthWithNull * sizeof(char16_t))) { - JS_ReportOutOfMemory(cx); - return nullptr; + ReportOutOfMemory(cx); + return mozilla::Nothing(); } decompressed[ss.length()] = 0; + auto& strings = cx->runtime()->sharedImmutableStrings(); + auto deduped = strings.getOrCreate(mozilla::Move(decompressed), ss.length()); + if (!deduped) { + ReportOutOfMemory(cx); + return mozilla::Nothing(); + } + // Decompressing a huge script is expensive. With lazy parsing and // relazification, this can happen repeatedly, so conservatively go // back to storing the data uncompressed to avoid wasting too much // time yo-yoing back and forth between compressed and uncompressed. const size_t HUGE_SCRIPT = 5 * 1024 * 1024; if (lengthWithNull > HUGE_SCRIPT) { - auto& strings = cx->runtime()->sharedImmutableStrings(); - auto str = strings.getOrCreate(mozilla::Move(decompressed), ss.length()); - if (!str) { - JS_ReportOutOfMemory(cx); - return nullptr; - } - ss.data = SourceType(Uncompressed(mozilla::Move(*str))); - return ss.uncompressedChars(); + ss.data = SourceType(Uncompressed(deduped->clone())); + return mozilla::Some(mozilla::Move(*deduped)); } - ReturnType ret = decompressed.get(); - if (!cx->runtime()->uncompressedSourceCache.put(&ss, Move(decompressed), holder)) { - JS_ReportOutOfMemory(cx); - return nullptr; + if (!cx->runtime()->uncompressedSourceCache.put(&ss, deduped->clone())) { + ReportOutOfMemory(cx); + return mozilla::Nothing(); } - return ret; + + return mozilla::Some(mozilla::Move(*deduped)); } ReturnType match(Missing&) { - MOZ_CRASH("ScriptSource::chars() on ScriptSource with SourceType = Missing"); - return nullptr; + MOZ_CRASH("ScriptSource::sourceText() on ScriptSource with SourceType = Missing"); + return mozilla::Nothing(); } }; - CharsMatcher cm(cx, *this, holder); + SourceTextMatcher cm(cx, *this); return data.match(cm); } @@ -2004,22 +1934,20 @@ JSFlatString* ScriptSource::substring(JSContext* cx, uint32_t start, uint32_t stop) { MOZ_ASSERT(start <= stop); - UncompressedSourceCache::AutoHoldEntry holder; - const char16_t* chars = this->chars(cx, holder); - if (!chars) + auto text = sourceText(cx); + if (!text) return nullptr; - return NewStringCopyN(cx, chars + start, stop - start); + return NewStringCopyN(cx, text->chars() + start, stop - start); } JSFlatString* ScriptSource::substringDontDeflate(JSContext* cx, uint32_t start, uint32_t stop) { MOZ_ASSERT(start <= stop); - UncompressedSourceCache::AutoHoldEntry holder; - const char16_t* chars = this->chars(cx, holder); - if (!chars) + auto text = sourceText(cx); + if (!text) return nullptr; - return NewStringCopyNDontDeflate(cx, chars + start, stop - start); + return NewStringCopyNDontDeflate(cx, text->chars() + start, stop - start); } MOZ_MUST_USE bool @@ -4468,19 +4396,17 @@ LazyScriptHashPolicy::match(JSScript* script, const Lookup& lookup) return false; } - UncompressedSourceCache::AutoHoldEntry holder; - - const char16_t* scriptChars = script->scriptSource()->chars(cx, holder); - if (!scriptChars) + auto scriptText = script->scriptSource()->sourceText(cx); + if (!scriptText) return false; - const char16_t* lazyChars = lazy->scriptSource()->chars(cx, holder); - if (!lazyChars) + auto lazyText = lazy->scriptSource()->sourceText(cx); + if (!lazyText) return false; size_t begin = script->sourceStart(); size_t length = script->sourceEnd() - begin; - return !memcmp(scriptChars + begin, lazyChars + begin, length); + return !memcmp(scriptText->chars() + begin, lazyText->chars() + begin, length); } void diff --git a/js/src/jsscript.h b/js/src/jsscript.h index e5dd7a82846e..76bdc5ba4109 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -10,6 +10,8 @@ #define jsscript_h #include "mozilla/Atomics.h" +#include "mozilla/Attributes.h" +#include "mozilla/Maybe.h" #include "mozilla/MemoryReporting.h" #include "mozilla/PodOperations.h" #include "mozilla/Variant.h" @@ -576,45 +578,20 @@ class ScriptSource; class UncompressedSourceCache { - typedef HashMap, - SystemAllocPolicy> Map; + using Map = HashMap, + SystemAllocPolicy>; - public: - // Hold an entry in the source data cache and prevent it from being purged on GC. - class AutoHoldEntry - { - UncompressedSourceCache* cache_; - ScriptSource* source_; - UniqueTwoByteChars charsToFree_; - public: - explicit AutoHoldEntry(); - ~AutoHoldEntry(); - private: - void holdEntry(UncompressedSourceCache* cache, ScriptSource* source); - void deferDelete(UniqueTwoByteChars chars); - ScriptSource* source() const { return source_; } - friend class UncompressedSourceCache; - }; - - private: UniquePtr map_; - AutoHoldEntry* holder_; public: - UncompressedSourceCache() : holder_(nullptr) {} - - const char16_t* lookup(ScriptSource* ss, AutoHoldEntry& asp); - bool put(ScriptSource* ss, UniqueTwoByteChars chars, AutoHoldEntry& asp); + UncompressedSourceCache() { } + MOZ_MUST_USE mozilla::Maybe lookup(ScriptSource* ss); + bool put(ScriptSource* ss, SharedImmutableTwoByteString&& chars); void purge(); - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf); - - private: - void holdEntry(AutoHoldEntry& holder, ScriptSource* ss); - void releaseEntry(AutoHoldEntry& holder); }; class ScriptSource @@ -764,7 +741,11 @@ class ScriptSource MOZ_ASSERT(hasSourceData()); return argumentsNotIncluded_; } - const char16_t* chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& asp); + + // Get a handle on the underlying source text. Returns mozilla::Nothing on + // OOM failure. + MOZ_MUST_USE mozilla::Maybe sourceText(JSContext* cx); + JSFlatString* substring(JSContext* cx, uint32_t start, uint32_t stop); JSFlatString* substringDontDeflate(JSContext* cx, uint32_t start, uint32_t stop); void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, From 8031f0ba5cb2247541df12ef46be91805fe09af5 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Tue, 10 May 2016 15:45:01 -0700 Subject: [PATCH 03/56] Bug 1271407 - Remove unnecessary methods from `js::ScriptSource`; r=luke This commit removes the following methods from `js::ScriptSource`: * `compressedChars` * `compressedBytes` * `uncompressedChars` They are throwbacks from when `ScriptSource` had this big, hand-rolled tagged union, and these methods were getters that did all sanity asserts on the tag state. That union has since been replaced with a `mozilla::Variant`, so we should just use `mozilla::Variant`'s type-safe accessors instead. --- js/src/jsscript.cpp | 12 ++++++++---- js/src/jsscript.h | 22 ++++------------------ 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index ec62710c357a..3e89b6da6603 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1884,8 +1884,8 @@ ScriptSource::sourceText(JSContext* cx) return mozilla::Nothing(); } - if (!DecompressString((const unsigned char*) ss.compressedData(), - ss.compressedBytes(), + if (!DecompressString((const unsigned char*) c.raw.chars(), + c.raw.length(), reinterpret_cast(decompressed.get()), lengthWithNull * sizeof(char16_t))) { @@ -2051,6 +2051,8 @@ ScriptSource::setSourceCopy(ExclusiveContext* cx, SourceBufferHolder& srcBuf, SourceCompressionTask::ResultType SourceCompressionTask::work() { + MOZ_ASSERT(ss->data.is()); + // Try to keep the maximum memory usage down by only allocating half the // size of the string, first. size_t inputBytes = ss->length() * sizeof(char16_t); @@ -2059,7 +2061,9 @@ SourceCompressionTask::work() if (!compressed) return OOM; - Compressor comp(reinterpret_cast(ss->uncompressedChars()), inputBytes); + const char16_t* chars = ss->data.as().string.chars(); + Compressor comp(reinterpret_cast(chars), + inputBytes); if (!comp.init()) return OOM; @@ -2127,7 +2131,7 @@ ScriptSource::performXDR(XDRState* xdr) } ReturnType match(Compressed& c) { - return c.nbytes(); + return c.raw.length(); } ReturnType match(Missing&) { diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 76bdc5ba4109..cf7caef48e73 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -620,14 +620,12 @@ class ScriptSource struct Compressed { SharedImmutableString raw; - size_t length; + size_t uncompressedLength; - Compressed(SharedImmutableString&& raw, size_t length) + Compressed(SharedImmutableString&& raw, size_t uncompressedLength) : raw(mozilla::Move(raw)) - , length(length) + , uncompressedLength(uncompressedLength) { } - - size_t nbytes() const { return raw.length(); } }; using SourceType = mozilla::Variant; @@ -724,7 +722,7 @@ class ScriptSource } ReturnType match(const Compressed& c) { - return c.length; + return c.uncompressedLength; } ReturnType match(const Missing& m) { @@ -751,18 +749,6 @@ class ScriptSource void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::ScriptSourceInfo* info) const; - const char16_t* uncompressedChars() const { - return data.as().string.chars(); - } - - const void* compressedData() const { - return static_cast(data.as().raw.chars()); - } - - size_t compressedBytes() const { - return data.as().nbytes(); - } - MOZ_MUST_USE bool setSource(ExclusiveContext* cx, mozilla::UniquePtr&& source, size_t length); From 9812410679cc659e9fa6dc8685931929b02c4122 Mon Sep 17 00:00:00 2001 From: Yura Zenevich Date: Tue, 10 May 2016 14:50:14 -0400 Subject: [PATCH 04/56] Bug 1271095 - fixing padding for JS terminal input when pasting multiline code. r=bgrins MozReview-Commit-ID: 6gTfjzn0v7h --HG-- extra : rebase_source : 157582e715642ae701d25558932ec05622304c9f --- devtools/client/themes/webconsole.css | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/devtools/client/themes/webconsole.css b/devtools/client/themes/webconsole.css index 9d9759c866af..89564a4fb7e8 100644 --- a/devtools/client/themes/webconsole.css +++ b/devtools/client/themes/webconsole.css @@ -406,7 +406,6 @@ a { .jsterm-input-node, .jsterm-complete-node { border: none; - padding: 4px; padding-inline-start: 20px; margin: 0; -moz-appearance: none; @@ -441,6 +440,10 @@ a { :-moz-any(.jsterm-input-node, .jsterm-complete-node) > .textbox-input-box > .textbox-textarea { overflow-x: hidden; + /* Set padding for console input on textbox to make sure it is inlcuded in + scrollHeight that is used when resizing JSTerminal's input. Note: textbox + default style has important already */ + padding: 4px 0 !important; } .inlined-variables-view .message-body { From 3e84a978e6e78f773569846bf8a58a9f078fe017 Mon Sep 17 00:00:00 2001 From: Jakob Olesen Date: Tue, 10 May 2016 15:53:38 -0700 Subject: [PATCH 05/56] Bug 1136226 - Unify Bailout_NonSimd*Input. r=nbp We have a lot of SIMD types in Ion now, and there is little benefit in maintaining a separate bailout kind for each type. Instead, use a single Bailout_NonSimd bailout kind to indicate that SimdUnbox didn't get the SIMD type it was expecting. --- js/src/jit/BaselineBailouts.cpp | 4 +--- js/src/jit/CodeGenerator.cpp | 12 ++++++++++-- js/src/jit/IonTypes.h | 12 +++--------- js/src/jit/Lowering.cpp | 18 +----------------- 4 files changed, 15 insertions(+), 31 deletions(-) diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp index 437f59c9110c..f4b68721e89d 100644 --- a/js/src/jit/BaselineBailouts.cpp +++ b/js/src/jit/BaselineBailouts.cpp @@ -1888,9 +1888,7 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo) case Bailout_NonObjectInput: case Bailout_NonStringInput: case Bailout_NonSymbolInput: - case Bailout_NonSimdBool32x4Input: - case Bailout_NonSimdInt32x4Input: - case Bailout_NonSimdFloat32x4Input: + case Bailout_UnexpectedSimdInput: case Bailout_NonSharedTypedArrayInput: case Bailout_Debugger: case Bailout_UninitializedThis: diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 6d81e7fb7f09..0a7b576f0518 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -5508,8 +5508,12 @@ CodeGenerator::visitSimdBox(LSimdBox* lir) Address objectData(object, InlineTypedObject::offsetOfDataStart()); switch (type) { - case MIRType::Bool32x4: + case MIRType::Int8x16: + case MIRType::Int16x8: case MIRType::Int32x4: + case MIRType::Bool8x16: + case MIRType::Bool16x8: + case MIRType::Bool32x4: masm.storeUnalignedSimd128Int(in, objectData); break; case MIRType::Float32x4: @@ -5586,8 +5590,12 @@ CodeGenerator::visitSimdUnbox(LSimdUnbox* lir) // Load the value from the data of the InlineTypedObject. Address objectData(object, InlineTypedObject::offsetOfDataStart()); switch (lir->mir()->type()) { - case MIRType::Bool32x4: + case MIRType::Int8x16: + case MIRType::Int16x8: case MIRType::Int32x4: + case MIRType::Bool8x16: + case MIRType::Bool16x8: + case MIRType::Bool32x4: masm.loadUnalignedSimd128Int(objectData, simd); break; case MIRType::Float32x4: diff --git a/js/src/jit/IonTypes.h b/js/src/jit/IonTypes.h index 2ff69f00e82c..908c6d391bb9 100644 --- a/js/src/jit/IonTypes.h +++ b/js/src/jit/IonTypes.h @@ -104,9 +104,7 @@ enum BailoutKind Bailout_NonSymbolInput, // SIMD Unbox expects a given type, bails out if it doesn't match. - Bailout_NonSimdBool32x4Input, - Bailout_NonSimdInt32x4Input, - Bailout_NonSimdFloat32x4Input, + Bailout_UnexpectedSimdInput, // Atomic operations require shared memory, bail out if the typed array // maps unshared memory. @@ -213,12 +211,8 @@ BailoutKindString(BailoutKind kind) return "Bailout_NonStringInput"; case Bailout_NonSymbolInput: return "Bailout_NonSymbolInput"; - case Bailout_NonSimdBool32x4Input: - return "Bailout_NonSimdBool32x4Input"; - case Bailout_NonSimdInt32x4Input: - return "Bailout_NonSimdInt32x4Input"; - case Bailout_NonSimdFloat32x4Input: - return "Bailout_NonSimdFloat32x4Input"; + case Bailout_UnexpectedSimdInput: + return "Bailout_UnexpectedSimdInput"; case Bailout_NonSharedTypedArrayInput: return "Bailout_NonSharedTypedArrayInput"; case Bailout_Debugger: diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 55bbf5bcd8b8..24c11df038f1 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -4282,24 +4282,8 @@ LIRGenerator::visitSimdUnbox(MSimdUnbox* ins) MOZ_ASSERT(ins->input()->type() == MIRType::Object); MOZ_ASSERT(IsSimdType(ins->type())); LUse in = useRegister(ins->input()); - - BailoutKind kind; - switch (ins->type()) { - case MIRType::Bool32x4: - kind = Bailout_NonSimdBool32x4Input; - break; - case MIRType::Int32x4: - kind = Bailout_NonSimdInt32x4Input; - break; - case MIRType::Float32x4: - kind = Bailout_NonSimdFloat32x4Input; - break; - default: - MOZ_CRASH("Unexpected SIMD Type."); - } - LSimdUnbox* lir = new(alloc()) LSimdUnbox(in, temp()); - assignSnapshot(lir, kind); + assignSnapshot(lir, Bailout_UnexpectedSimdInput); define(lir, ins); } From 56561ae6739d042463b81923101c7fb7b3343ad9 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Fri, 22 Apr 2016 15:39:56 +1200 Subject: [PATCH 06/56] Bug 1260611 - Part 1: Opt-in to waiting for compositor recycling for TextureClientRecycleAllocator. r=sotaro --HG-- extra : rebase_source : 1035ebcfaa2bd67a259b0f177ed4b9fef92a5792 --- gfx/layers/client/TextureClient.cpp | 1 + gfx/layers/client/TextureClient.h | 8 ++++++ .../client/TextureClientRecycleAllocator.cpp | 27 +++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index 0a8650334961..1890b58afc54 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -963,6 +963,7 @@ TextureClient::TextureClient(TextureData* aData, TextureFlags aFlags, ClientIPCA , mExpectedDtRefs(0) #endif , mIsLocked(false) +, mInUse(false) , mAddedToCompositableClient(false) , mWorkaroundAnnoyingSharedSurfaceLifetimeIssues(false) , mWorkaroundAnnoyingSharedSurfaceOwnershipIssues(false) diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index bf1e00bd2bfa..4d932830f64e 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -359,6 +359,13 @@ public: bool CanExposeMappedData() const { return mInfo.canExposeMappedData; } + /* TextureClientRecycleAllocator tracking to decide if we need + * to check with the compositor before recycling. + * Should be superceeded (and removed) by bug 1252835. + */ + void SetInUse(bool aInUse) { mInUse = aInUse; } + bool IsInUse() { return mInUse; } + /** * Returns a DrawTarget to draw into the TextureClient. * This function should never be called when not on the main thread! @@ -639,6 +646,7 @@ protected: uint32_t mExpectedDtRefs; #endif bool mIsLocked; + bool mInUse; bool mAddedToCompositableClient; bool mWorkaroundAnnoyingSharedSurfaceLifetimeIssues; diff --git a/gfx/layers/client/TextureClientRecycleAllocator.cpp b/gfx/layers/client/TextureClientRecycleAllocator.cpp index 34a49656ce8d..0aedee420710 100644 --- a/gfx/layers/client/TextureClientRecycleAllocator.cpp +++ b/gfx/layers/client/TextureClientRecycleAllocator.cpp @@ -181,6 +181,7 @@ TextureClientRecycleAllocator::CreateOrRecycle(ITextureClientAllocationHelper& a // Make sure the texture holds a reference to us, and ask it to call RecycleTextureClient when its // ref count drops to 1. client->SetRecycleAllocator(this); + client->SetInUse(true); return client.forget(); } @@ -204,9 +205,35 @@ TextureClientRecycleAllocator::ShrinkToMinimumSize() } } +class TextureClientWaitTask : public Runnable +{ +public: + explicit TextureClientWaitTask(TextureClient* aClient) + : mTextureClient(aClient) + {} + + NS_IMETHOD Run() override + { + mTextureClient->WaitForCompositorRecycle(); + return NS_OK; + } + +private: + RefPtr mTextureClient; +}; + void TextureClientRecycleAllocator::RecycleTextureClient(TextureClient* aClient) { + if (aClient->IsInUse()) { + aClient->SetInUse(false); + // This adds another ref to aClient, and drops it after a round trip + // to the compositor. We should then get this callback a second time + // and can recycle properly. + RefPtr task = new TextureClientWaitTask(aClient); + mSurfaceAllocator->GetMessageLoop()->PostTask(task.forget()); + return; + } // Clearing the recycle allocator drops a reference, so make sure we stay alive // for the duration of this function. RefPtr kungFuDeathGrip(this); From 35ecd4fc8fa61859b57aa9965bd1884a3be3c85a Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Wed, 11 May 2016 10:53:46 +1200 Subject: [PATCH 07/56] Bug 1260611 - Part 2: Block CompositorD3D11 after presenting until the previous frame is complete. r=Bas --HG-- extra : rebase_source : 80a439a8ffa99a106e038102780ffb022966ecce --- gfx/layers/d3d11/CompositorD3D11.cpp | 24 ++++++++++++++++++++++++ gfx/layers/d3d11/CompositorD3D11.h | 2 ++ 2 files changed, 26 insertions(+) diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index af15685959cf..55e90f2f3813 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -1208,6 +1208,13 @@ CompositorD3D11::EndFrame() return; } + RefPtr query; + CD3D11_QUERY_DESC desc(D3D11_QUERY_EVENT); + mDevice->CreateQuery(&desc, getter_AddRefs(query)); + if (query) { + mContext->End(query); + } + UINT presentInterval = 0; if (gfxWindowsPlatform::GetPlatform()->IsWARP()) { @@ -1268,6 +1275,23 @@ CompositorD3D11::EndFrame() } } + // Block until the previous frame's work has been completed. + if (mQuery) { + TimeStamp start = TimeStamp::Now(); + BOOL result; + while (mContext->GetData(mQuery, &result, sizeof(BOOL), 0) != S_OK) { + if (mDevice->GetDeviceRemovedReason() != S_OK) { + break; + } + if ((TimeStamp::Now() - start) > TimeDuration::FromSeconds(2)) { + break; + } + Sleep(0); + } + } + // Store the query for this frame so we can flush it next time. + mQuery = query; + mCurrentRT = nullptr; } diff --git a/gfx/layers/d3d11/CompositorD3D11.h b/gfx/layers/d3d11/CompositorD3D11.h index 23844f94b1b3..d4115bb88990 100644 --- a/gfx/layers/d3d11/CompositorD3D11.h +++ b/gfx/layers/d3d11/CompositorD3D11.h @@ -186,6 +186,8 @@ private: RefPtr mDefaultRT; RefPtr mCurrentRT; + RefPtr mQuery; + DeviceAttachmentsD3D11* mAttachments; LayoutDeviceIntSize mSize; From 814c8dcc8086f4367dd77a09e087ef15be6ffe4b Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Wed, 11 May 2016 10:55:17 +1200 Subject: [PATCH 08/56] Bug 1260611 - Part 3: Hold on to TextureHosts until the following composite is done. r=sotaro --HG-- extra : rebase_source : adfc1ae3f241a965b8df8035154e861449a7157e --- gfx/layers/composite/ImageHost.cpp | 5 +++++ gfx/layers/composite/LayerManagerComposite.cpp | 3 +++ gfx/layers/composite/LayerManagerComposite.h | 7 +++++++ 3 files changed, 15 insertions(+) diff --git a/gfx/layers/composite/ImageHost.cpp b/gfx/layers/composite/ImageHost.cpp index 369076405c7c..29b4ea158f88 100644 --- a/gfx/layers/composite/ImageHost.cpp +++ b/gfx/layers/composite/ImageHost.cpp @@ -331,6 +331,11 @@ ImageHost::Composite(LayerComposite* aLayer, TimedImage* img = &mImages[imageIndex]; img->mTextureHost->SetCompositor(GetCompositor()); + // If this TextureHost will be recycled, then make sure we hold a reference to + // it until we're sure that the compositor has finished reading from it. + if (img->mTextureHost->GetFlags() & TextureFlags::RECYCLE) { + aLayer->GetLayerManager()->HoldTextureUntilNextComposite(img->mTextureHost); + } SetCurrentTextureHost(img->mTextureHost); { diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index 340895b033ab..0648be688498 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -393,6 +393,9 @@ LayerManagerComposite::EndTransaction(const TimeStamp& aTimeStamp, if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) { MOZ_ASSERT(!aTimeStamp.IsNull()); UpdateAndRender(); + + mPreviousHeldTextureHosts.Clear(); + mPreviousHeldTextureHosts.SwapElements(mCurrentHeldTextureHosts); } else { // Modified the layer tree. mGeometryChanged = true; diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 10a7fc541bae..1d2a9022a7fb 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -337,6 +337,10 @@ public: void ForcePresent() { mCompositor->ForcePresent(); } + void HoldTextureUntilNextComposite(TextureHost* aTextureHost) { + mCurrentHeldTextureHosts.AppendElement(aTextureHost); + } + private: /** Region we're clipping our current drawing to. */ nsIntRegion mClippingRegion; @@ -397,6 +401,9 @@ private: nsTArray mImageCompositeNotifications; + nsTArray> mCurrentHeldTextureHosts; + nsTArray> mPreviousHeldTextureHosts; + /** * Context target, nullptr when drawing directly to our swap chain. */ From f123b681bb249cbee346ecbf80ff5ed05a87df72 Mon Sep 17 00:00:00 2001 From: Ralph Giles Date: Thu, 5 May 2016 15:29:17 -0700 Subject: [PATCH 09/56] Bug 1270091 - Handle missing function names. r=dminor If the symbols file doesn't give a function name, substitute 'unnamed_function'. A more complete fix would be to catch all ValueError exceptions and continue sensibly, but this addresses the immediate issue with the output from `rustc -g`. MozReview-Commit-ID: 666ruvLlJ5t --- tools/rb/fix_stack_using_bpsyms.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/rb/fix_stack_using_bpsyms.py b/tools/rb/fix_stack_using_bpsyms.py index 156acb5882cb..65622a259ef9 100755 --- a/tools/rb/fix_stack_using_bpsyms.py +++ b/tools/rb/fix_stack_using_bpsyms.py @@ -43,7 +43,10 @@ class SymbolFile: # http://code.google.com/p/google-breakpad/wiki/SymbolFiles if line.startswith("FUNC "): # FUNC
- (junk, rva, size, ss, name) = line.split(None, 4) + bits = line.split(None, 4) + if len(bits) < 5: + bits.append('unnamed_function') + (junk, rva, size, ss, name) = bits rva = int(rva,16) funcs[rva] = name addrs.append(rva) From df51e79d6ea12ac82ec9e08a9e383df5c8140cfd Mon Sep 17 00:00:00 2001 From: Ralph Giles Date: Thu, 28 Apr 2016 11:56:02 -0700 Subject: [PATCH 10/56] Bug 1268617 - Pass -g to rustc on debug builds. r=ted Enable debug output from the rust compiler when we're doing so for the C/C++ compilers. MozReview-Commit-ID: K0iqlPZ1Thu --- config/config.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/config.mk b/config/config.mk index 7e7c7b1edc2e..301cce90bcf7 100644 --- a/config/config.mk +++ b/config/config.mk @@ -136,6 +136,7 @@ PYTHON_PATH = $(PYTHON) $(topsrcdir)/config/pythonpath.py _DEBUG_ASFLAGS := _DEBUG_CFLAGS := _DEBUG_LDFLAGS := +_DEBUG_RUSTFLAGS := ifneq (,$(MOZ_DEBUG)$(MOZ_DEBUG_SYMBOLS)) ifeq ($(AS),$(YASM)) @@ -151,12 +152,14 @@ ifneq (,$(MOZ_DEBUG)$(MOZ_DEBUG_SYMBOLS)) endif _DEBUG_CFLAGS += $(MOZ_DEBUG_FLAGS) _DEBUG_LDFLAGS += $(MOZ_DEBUG_LDFLAGS) + _DEBUG_RUSTFLAGS += -g endif ASFLAGS += $(_DEBUG_ASFLAGS) OS_CFLAGS += $(_DEBUG_CFLAGS) OS_CXXFLAGS += $(_DEBUG_CFLAGS) OS_LDFLAGS += $(_DEBUG_LDFLAGS) +RUSTFLAGS += $(_DEBUG_RUSTFLAGS) # XXX: What does this? Bug 482434 filed for better explanation. ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_) From f2f4e5708d152c78773e0e95e169d7f51cbd177c Mon Sep 17 00:00:00 2001 From: Kit Cambridge Date: Mon, 9 May 2016 20:54:05 -0700 Subject: [PATCH 11/56] Bug 1206424 - Ensure `daysElapsed` is always non-negative when updating the push quota. r=wchen --HG-- extra : rebase_source : 4c203d359f7bf965591442a3755675fd1d37ba3c --- dom/push/PushRecord.jsm | 13 ++++--- .../xpcshell/test_quota_with_notification.js | 37 +++++++++++++++++-- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/dom/push/PushRecord.jsm b/dom/push/PushRecord.jsm index 84bf1e08b507..1d2a3fcbf46f 100644 --- a/dom/push/PushRecord.jsm +++ b/dom/push/PushRecord.jsm @@ -49,10 +49,11 @@ function PushRecord(props) { PushRecord.prototype = { setQuota(suggestedQuota) { - if (this.quotaApplies() && !isNaN(suggestedQuota) && suggestedQuota >= 0) { - this.quota = suggestedQuota; + if (this.quotaApplies()) { + let quota = +suggestedQuota; + this.quota = quota >= 0 ? quota : prefs.get("maxQuotaPerSubscription"); } else { - this.resetQuota(); + this.quota = Infinity; } }, @@ -75,8 +76,10 @@ PushRecord.prototype = { } if (lastVisit > this.lastPush) { // If the user visited the site since the last time we received a - // notification, reset the quota. - let daysElapsed = (Date.now() - lastVisit) / 24 / 60 / 60 / 1000; + // notification, reset the quota. `Math.max(0, ...)` ensures the + // last visit date isn't in the future. + let daysElapsed = + Math.max(0, (Date.now() - lastVisit) / 24 / 60 / 60 / 1000); this.quota = Math.min( Math.round(8 * Math.pow(daysElapsed, -0.8)), prefs.get("maxQuotaPerSubscription") diff --git a/dom/push/test/xpcshell/test_quota_with_notification.js b/dom/push/test/xpcshell/test_quota_with_notification.js index ba60f632b311..f3ff5a9dd177 100644 --- a/dom/push/test/xpcshell/test_quota_with_notification.js +++ b/dom/push/test/xpcshell/test_quota_with_notification.js @@ -10,6 +10,8 @@ Cu.import("resource://gre/modules/Task.jsm"); const userAgentID = 'aaabf1f8-2f68-44f1-a920-b88e9e7d7559'; const nsIPushQuotaManager = Components.interfaces.nsIPushQuotaManager; +const MS_IN_ONE_DAY = 1 * 24 * 60 * 60 * 1000; + function run_test() { do_get_profile(); setPrefs({ @@ -41,16 +43,34 @@ add_task(function* test_expiration_origin_threshold() { originAttributes: '', quota: 16, }); + yield db.put({ + channelID: 'last-visit-future', + pushEndpoint: 'https://example.org/push/2', + scope: 'https://example.info/~marty', + pushCount: 0, + lastPush: 0, + version: null, + originAttributes: '', + quota: 8, + }); // A visit one day ago should provide a quota of 8 messages. yield PlacesTestUtils.addVisits({ uri: 'https://example.com/login', title: 'Sign in to see your auctions', - visitDate: (Date.now() - 1 * 24 * 60 * 60 * 1000) * 1000, + visitDate: (Date.now() - MS_IN_ONE_DAY) * 1000, transition: Ci.nsINavHistoryService.TRANSITION_LINK }); + // Make sure we calculate the quota correctly for visit dates in the + // future (bug 1206424). + yield PlacesTestUtils.addVisits({ + uri: 'https://example.info/~marty/flux-capacitor.pdf', + title: 'Flux Capacitor Design', + visitDate: (Date.now() + MS_IN_ONE_DAY) * 1000, + transition: Ci.nsINavHistoryService.TRANSITION_TYPED + }); - let numMessages = 10; + let numMessages = 11; let updates = 0; let notifyPromise = promiseObserverNotification(PushServiceComponent.pushTopic, (subject, data) => { @@ -70,7 +90,7 @@ add_task(function* test_expiration_origin_threshold() { let quotaUpdateCount = 0; PushService._updateQuotaTestCallback = function() { quotaUpdateCount++; - if (quotaUpdateCount == 10) { + if (quotaUpdateCount == numMessages) { resolve(); } }; @@ -99,6 +119,13 @@ add_task(function* test_expiration_origin_threshold() { }], })); } + this.serverSendMsg(JSON.stringify({ + messageType: 'notification', + updates: [{ + channelID: 'last-visit-future', + version: 1, + }], + })); }, onUnregister(request) { ok(false, "Channel should not be unregistered."); @@ -117,4 +144,8 @@ add_task(function* test_expiration_origin_threshold() { let expiredRecord = yield db.getByKeyID('f56645a9-1f32-4655-92ad-ddc37f6d54fb'); notStrictEqual(expiredRecord.quota, 0, 'Expired record not updated'); + + let futureRecord = yield db.getByKeyID('last-visit-future'); + equal(futureRecord.quota, 15, + 'Should reset and reduce the quota for visits in the future'); }); From b2c801fe1be23d6866bf0767ee5f15d4e81a33ca Mon Sep 17 00:00:00 2001 From: Milan Sreckovic Date: Mon, 2 May 2016 09:36:00 -0400 Subject: [PATCH 12/56] Bug 1269244 - Block nhasusstrixosd.dll and nhasusstrixdevprops.dll. r=jrmuizel --HG-- extra : rebase_source : c3a9e9f7732ac0dd733ce292c37b4de173231613 --- mozglue/build/WindowsDllBlocklist.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mozglue/build/WindowsDllBlocklist.cpp b/mozglue/build/WindowsDllBlocklist.cpp index 98fd1c844ffa..ebb0f9cfba4e 100644 --- a/mozglue/build/WindowsDllBlocklist.cpp +++ b/mozglue/build/WindowsDllBlocklist.cpp @@ -205,6 +205,10 @@ static DllBlockInfo sWindowsDllBlocklist[] = { { "ss2osd.dll", ALL_VERSIONS }, { "ss2devprops.dll", ALL_VERSIONS }, + // NHASUSSTRIXOSD.DLL, bug 1269244 + { "nhasusstrixosd.dll", ALL_VERSIONS }, + { "nhasusstrixdevprops.dll", ALL_VERSIONS }, + { nullptr, 0 } }; From e3da2b3d0dc5c8e3cee14d70f2487a7dbf1ddec8 Mon Sep 17 00:00:00 2001 From: Mason Chang Date: Mon, 9 May 2016 12:34:00 -0400 Subject: [PATCH 13/56] Bug 1270640 - Part 1: Always enable normal hinting with skia unless we explicitly have grayscale aa. r=kats --HG-- extra : rebase_source : 5a96292b0f7a98e60d052b31eb1d2cc35ea636ea --- gfx/2d/DrawTargetSkia.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp index 8f2ba503d0e6..bbe99fb4fbde 100644 --- a/gfx/2d/DrawTargetSkia.cpp +++ b/gfx/2d/DrawTargetSkia.cpp @@ -634,22 +634,27 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont, paint.mPaint.setAntiAlias(false); } } else { - // SkFontHost_cairo does not support subpixel text, so only enable it for other font hosts. + // SkFontHost_cairo does not support subpixel text positioning, + // so only enable it for other font hosts. paint.mPaint.setSubpixelText(true); if (aFont->GetType() == FontType::MAC && - (shouldLCDRenderText || aOptions.mAntialiasMode == AntialiasMode::GRAY)) { - // SkFontHost_mac only enables CG Font Smoothing if hinting is disabled. - // CG Font Smoothing normally enables subpixel AA in CG, but Skia supports - // font smoothing with grayscale AA. - // SkFontHost_mac only supports subpixel antialiasing when hinting is turned off. - // We can get grayscale AA if we have -moz-osx-font-smoothing: grayscale - // explicitly enabled or for transparent surfaces. - // If we have AA grayscale explicit through the draw options, - // then we want to disable font smoothing. - // If we have a transparent surface, shouldLCDRenderText will be false. But unless - // grayscale font smoothing is explicitly requested, we still want Skia to use - // CG Font smoothing. + aOptions.mAntialiasMode == AntialiasMode::GRAY) { + // Normally, Skia enables LCD FontSmoothing which creates thicker fonts + // and also enables subpixel AA. CoreGraphics without font smoothing + // explicitly creates thinner fonts and grayscale AA. + // CoreGraphics doesn't support a configuration that produces thicker + // fonts with grayscale AA as LCD Font Smoothing enables or disables both. + // However, Skia supports it by enabling font smoothing (producing subpixel AA) + // and converts it to grayscale AA. Since Skia doesn't support subpixel AA on + // transparent backgrounds, we still want font smoothing for the thicker fonts, + // even if it is grayscale AA. + // + // With explicit Grayscale AA (from -moz-osx-font-smoothing:grayscale), + // we want to have grayscale AA with no smoothing at all. This means + // disabling the LCD font smoothing behaviour. + // To accomplish this we have to explicitly disable hinting, + // and disable LCDRenderText. paint.mPaint.setHinting(SkPaint::kNo_Hinting); } else { paint.mPaint.setHinting(SkPaint::kNormal_Hinting); From a708ef285b59bef6bca6420e6e2cfd11809dc8b2 Mon Sep 17 00:00:00 2001 From: Mason Chang Date: Mon, 9 May 2016 12:38:00 -0400 Subject: [PATCH 14/56] Bug 1270640 - Part 2: Reftest fuzzing for skia on OS X due to hinting changes. r=lsalzman --HG-- extra : rebase_source : f9f041a45eb9833009ab650962cf712b3e8c238a --- layout/reftests/text/reftest.list | 2 +- .../reftests/writing-mode/abspos/reftest.list | 192 +++++++++--------- 2 files changed, 97 insertions(+), 97 deletions(-) diff --git a/layout/reftests/text/reftest.list b/layout/reftests/text/reftest.list index 6c09b5d3c6aa..9155d9f7b7c6 100644 --- a/layout/reftests/text/reftest.list +++ b/layout/reftests/text/reftest.list @@ -145,7 +145,7 @@ HTTP(..) == zwnj-02.xhtml zwnj-02-ref.xhtml # HTTP(..) for ../filters.svg == 449555-1.html 449555-1-ref.html == 467722.html 467722-ref.html skip-if(B2G||Mulet) fuzzy-if(skiaContent,1,600) HTTP(..) == 475092-sub.html 475092-ref.html # Initial mulet triage: parity with B2G/B2G Desktop -fails-if(!winWidget&&!gtkWidget) skip-if(B2G||Mulet) fuzzy-if(skiaContent,64,3100) HTTP(..) == 475092-pos.html 475092-sub.html # bug 482596 # Initial mulet triage: parity with B2G/B2G Desktop +fails-if(!winWidget&&!gtkWidget) skip-if(B2G||Mulet) fuzzy-if(skiaContent,89,3100) HTTP(..) == 475092-pos.html 475092-sub.html # bug 482596 # Initial mulet triage: parity with B2G/B2G Desktop == 476378-soft-hyphen-fallback.html 476378-soft-hyphen-fallback-ref.html # Test for bug 484954 == rgba-text.html rgba-text-ref.html diff --git a/layout/reftests/writing-mode/abspos/reftest.list b/layout/reftests/writing-mode/abspos/reftest.list index bcc2f4e289ec..f186ea2dc257 100644 --- a/layout/reftests/writing-mode/abspos/reftest.list +++ b/layout/reftests/writing-mode/abspos/reftest.list @@ -4,102 +4,102 @@ default-preferences pref(layout.css.vertical-text.enabled,true) # All of these are fuzzy-if on skia content on OS X due to subpixel text positioning. -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-003.xht s71-abs-pos-non-replaced-vlr-003-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-005.xht s71-abs-pos-non-replaced-vlr-005-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-007.xht s71-abs-pos-non-replaced-vlr-007-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-009.xht s71-abs-pos-non-replaced-vlr-009-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-011.xht s71-abs-pos-non-replaced-vlr-011-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-013.xht s71-abs-pos-non-replaced-vlr-013-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-015.xht s71-abs-pos-non-replaced-vlr-015-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-017.xht s71-abs-pos-non-replaced-vlr-017-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-019.xht s71-abs-pos-non-replaced-vlr-019-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-021.xht s71-abs-pos-non-replaced-vlr-021-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-023.xht s71-abs-pos-non-replaced-vlr-023-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-025.xht s71-abs-pos-non-replaced-vlr-025-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-027.xht s71-abs-pos-non-replaced-vlr-027-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-029.xht s71-abs-pos-non-replaced-vlr-029-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-031.xht s71-abs-pos-non-replaced-vlr-031-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-033.xht s71-abs-pos-non-replaced-vlr-033-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-035.xht s71-abs-pos-non-replaced-vlr-035-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-037.xht s71-abs-pos-non-replaced-vlr-037-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-039.xht s71-abs-pos-non-replaced-vlr-039-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-041.xht s71-abs-pos-non-replaced-vlr-041-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-043.xht s71-abs-pos-non-replaced-vlr-043-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-045.xht s71-abs-pos-non-replaced-vlr-045-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-047.xht s71-abs-pos-non-replaced-vlr-047-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-049.xht s71-abs-pos-non-replaced-vlr-049-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-051.xht s71-abs-pos-non-replaced-vlr-051-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-053.xht s71-abs-pos-non-replaced-vlr-053-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-055.xht s71-abs-pos-non-replaced-vlr-055-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-057.xht s71-abs-pos-non-replaced-vlr-057-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-059.xht s71-abs-pos-non-replaced-vlr-059-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-061.xht s71-abs-pos-non-replaced-vlr-061-ref.xht -fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-063.xht s71-abs-pos-non-replaced-vlr-063-ref.xht -fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-065.xht s71-abs-pos-non-replaced-vlr-065-ref.xht -fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-067.xht s71-abs-pos-non-replaced-vlr-067-ref.xht -fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-069.xht s71-abs-pos-non-replaced-vlr-069-ref.xht -fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-071.xht s71-abs-pos-non-replaced-vlr-071-ref.xht -fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-073.xht s71-abs-pos-non-replaced-vlr-073-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-075.xht s71-abs-pos-non-replaced-vlr-075-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-077.xht s71-abs-pos-non-replaced-vlr-077-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-079.xht s71-abs-pos-non-replaced-vlr-079-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-081.xht s71-abs-pos-non-replaced-vlr-081-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-083.xht s71-abs-pos-non-replaced-vlr-083-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-085.xht s71-abs-pos-non-replaced-vlr-085-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-087.xht s71-abs-pos-non-replaced-vlr-087-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-089.xht s71-abs-pos-non-replaced-vlr-089-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-091.xht s71-abs-pos-non-replaced-vlr-091-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-093.xht s71-abs-pos-non-replaced-vlr-093-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-095.xht s71-abs-pos-non-replaced-vlr-095-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vlr-097.xht s71-abs-pos-non-replaced-vlr-097-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-002.xht s71-abs-pos-non-replaced-vrl-002-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-004.xht s71-abs-pos-non-replaced-vrl-004-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-006.xht s71-abs-pos-non-replaced-vrl-006-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-008.xht s71-abs-pos-non-replaced-vrl-008-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-010.xht s71-abs-pos-non-replaced-vrl-010-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-012.xht s71-abs-pos-non-replaced-vrl-012-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-014.xht s71-abs-pos-non-replaced-vrl-014-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-016.xht s71-abs-pos-non-replaced-vrl-016-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-018.xht s71-abs-pos-non-replaced-vrl-018-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-020.xht s71-abs-pos-non-replaced-vrl-020-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-022.xht s71-abs-pos-non-replaced-vrl-022-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-024.xht s71-abs-pos-non-replaced-vrl-024-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-026.xht s71-abs-pos-non-replaced-vrl-026-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-028.xht s71-abs-pos-non-replaced-vrl-028-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-030.xht s71-abs-pos-non-replaced-vrl-030-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-032.xht s71-abs-pos-non-replaced-vrl-032-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-034.xht s71-abs-pos-non-replaced-vrl-034-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-036.xht s71-abs-pos-non-replaced-vrl-036-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-038.xht s71-abs-pos-non-replaced-vrl-038-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-040.xht s71-abs-pos-non-replaced-vrl-040-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-042.xht s71-abs-pos-non-replaced-vrl-042-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-044.xht s71-abs-pos-non-replaced-vrl-044-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-046.xht s71-abs-pos-non-replaced-vrl-046-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-048.xht s71-abs-pos-non-replaced-vrl-048-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-050.xht s71-abs-pos-non-replaced-vrl-050-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-052.xht s71-abs-pos-non-replaced-vrl-052-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-054.xht s71-abs-pos-non-replaced-vrl-054-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-056.xht s71-abs-pos-non-replaced-vrl-056-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-058.xht s71-abs-pos-non-replaced-vrl-058-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-060.xht s71-abs-pos-non-replaced-vrl-060-ref.xht -fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-062.xht s71-abs-pos-non-replaced-vrl-062-ref.xht -fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-064.xht s71-abs-pos-non-replaced-vrl-064-ref.xht -fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-066.xht s71-abs-pos-non-replaced-vrl-066-ref.xht -fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-068.xht s71-abs-pos-non-replaced-vrl-068-ref.xht -fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-070.xht s71-abs-pos-non-replaced-vrl-070-ref.xht -fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-072.xht s71-abs-pos-non-replaced-vrl-072-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-074.xht s71-abs-pos-non-replaced-vrl-074-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-076.xht s71-abs-pos-non-replaced-vrl-076-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-078.xht s71-abs-pos-non-replaced-vrl-078-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-080.xht s71-abs-pos-non-replaced-vrl-080-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-082.xht s71-abs-pos-non-replaced-vrl-082-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-084.xht s71-abs-pos-non-replaced-vrl-084-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-086.xht s71-abs-pos-non-replaced-vrl-086-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-088.xht s71-abs-pos-non-replaced-vrl-088-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-090.xht s71-abs-pos-non-replaced-vrl-090-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-092.xht s71-abs-pos-non-replaced-vrl-092-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-094.xht s71-abs-pos-non-replaced-vrl-094-ref.xht -fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,128,160) == s71-abs-pos-non-replaced-vrl-096.xht s71-abs-pos-non-replaced-vrl-096-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-003.xht s71-abs-pos-non-replaced-vlr-003-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-005.xht s71-abs-pos-non-replaced-vlr-005-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-007.xht s71-abs-pos-non-replaced-vlr-007-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-009.xht s71-abs-pos-non-replaced-vlr-009-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-011.xht s71-abs-pos-non-replaced-vlr-011-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-013.xht s71-abs-pos-non-replaced-vlr-013-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-015.xht s71-abs-pos-non-replaced-vlr-015-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-017.xht s71-abs-pos-non-replaced-vlr-017-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-019.xht s71-abs-pos-non-replaced-vlr-019-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-021.xht s71-abs-pos-non-replaced-vlr-021-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-023.xht s71-abs-pos-non-replaced-vlr-023-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-025.xht s71-abs-pos-non-replaced-vlr-025-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-027.xht s71-abs-pos-non-replaced-vlr-027-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-029.xht s71-abs-pos-non-replaced-vlr-029-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-031.xht s71-abs-pos-non-replaced-vlr-031-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-033.xht s71-abs-pos-non-replaced-vlr-033-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-035.xht s71-abs-pos-non-replaced-vlr-035-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-037.xht s71-abs-pos-non-replaced-vlr-037-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-039.xht s71-abs-pos-non-replaced-vlr-039-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-041.xht s71-abs-pos-non-replaced-vlr-041-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-043.xht s71-abs-pos-non-replaced-vlr-043-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-045.xht s71-abs-pos-non-replaced-vlr-045-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-047.xht s71-abs-pos-non-replaced-vlr-047-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-049.xht s71-abs-pos-non-replaced-vlr-049-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-051.xht s71-abs-pos-non-replaced-vlr-051-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-053.xht s71-abs-pos-non-replaced-vlr-053-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-055.xht s71-abs-pos-non-replaced-vlr-055-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-057.xht s71-abs-pos-non-replaced-vlr-057-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-059.xht s71-abs-pos-non-replaced-vlr-059-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-061.xht s71-abs-pos-non-replaced-vlr-061-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-063.xht s71-abs-pos-non-replaced-vlr-063-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-065.xht s71-abs-pos-non-replaced-vlr-065-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-067.xht s71-abs-pos-non-replaced-vlr-067-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-069.xht s71-abs-pos-non-replaced-vlr-069-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-071.xht s71-abs-pos-non-replaced-vlr-071-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-073.xht s71-abs-pos-non-replaced-vlr-073-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-075.xht s71-abs-pos-non-replaced-vlr-075-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-077.xht s71-abs-pos-non-replaced-vlr-077-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-079.xht s71-abs-pos-non-replaced-vlr-079-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-081.xht s71-abs-pos-non-replaced-vlr-081-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-083.xht s71-abs-pos-non-replaced-vlr-083-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-085.xht s71-abs-pos-non-replaced-vlr-085-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-087.xht s71-abs-pos-non-replaced-vlr-087-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-089.xht s71-abs-pos-non-replaced-vlr-089-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-091.xht s71-abs-pos-non-replaced-vlr-091-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-093.xht s71-abs-pos-non-replaced-vlr-093-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-095.xht s71-abs-pos-non-replaced-vlr-095-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vlr-097.xht s71-abs-pos-non-replaced-vlr-097-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-002.xht s71-abs-pos-non-replaced-vrl-002-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-004.xht s71-abs-pos-non-replaced-vrl-004-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-006.xht s71-abs-pos-non-replaced-vrl-006-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-008.xht s71-abs-pos-non-replaced-vrl-008-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-010.xht s71-abs-pos-non-replaced-vrl-010-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-012.xht s71-abs-pos-non-replaced-vrl-012-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-014.xht s71-abs-pos-non-replaced-vrl-014-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-016.xht s71-abs-pos-non-replaced-vrl-016-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-018.xht s71-abs-pos-non-replaced-vrl-018-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-020.xht s71-abs-pos-non-replaced-vrl-020-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-022.xht s71-abs-pos-non-replaced-vrl-022-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-024.xht s71-abs-pos-non-replaced-vrl-024-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-026.xht s71-abs-pos-non-replaced-vrl-026-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-028.xht s71-abs-pos-non-replaced-vrl-028-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-030.xht s71-abs-pos-non-replaced-vrl-030-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-032.xht s71-abs-pos-non-replaced-vrl-032-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-034.xht s71-abs-pos-non-replaced-vrl-034-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-036.xht s71-abs-pos-non-replaced-vrl-036-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-038.xht s71-abs-pos-non-replaced-vrl-038-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-040.xht s71-abs-pos-non-replaced-vrl-040-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-042.xht s71-abs-pos-non-replaced-vrl-042-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-044.xht s71-abs-pos-non-replaced-vrl-044-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-046.xht s71-abs-pos-non-replaced-vrl-046-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-048.xht s71-abs-pos-non-replaced-vrl-048-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-050.xht s71-abs-pos-non-replaced-vrl-050-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-052.xht s71-abs-pos-non-replaced-vrl-052-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-054.xht s71-abs-pos-non-replaced-vrl-054-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-056.xht s71-abs-pos-non-replaced-vrl-056-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-058.xht s71-abs-pos-non-replaced-vrl-058-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-060.xht s71-abs-pos-non-replaced-vrl-060-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-062.xht s71-abs-pos-non-replaced-vrl-062-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-064.xht s71-abs-pos-non-replaced-vrl-064-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-066.xht s71-abs-pos-non-replaced-vrl-066-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-068.xht s71-abs-pos-non-replaced-vrl-068-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-070.xht s71-abs-pos-non-replaced-vrl-070-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-072.xht s71-abs-pos-non-replaced-vrl-072-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-074.xht s71-abs-pos-non-replaced-vrl-074-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-076.xht s71-abs-pos-non-replaced-vrl-076-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-078.xht s71-abs-pos-non-replaced-vrl-078-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-080.xht s71-abs-pos-non-replaced-vrl-080-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-082.xht s71-abs-pos-non-replaced-vrl-082-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-084.xht s71-abs-pos-non-replaced-vrl-084-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-086.xht s71-abs-pos-non-replaced-vrl-086-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-088.xht s71-abs-pos-non-replaced-vrl-088-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-090.xht s71-abs-pos-non-replaced-vrl-090-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-092.xht s71-abs-pos-non-replaced-vrl-092-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-094.xht s71-abs-pos-non-replaced-vrl-094-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) fuzzy-if(skiaContent,154,248) == s71-abs-pos-non-replaced-vrl-096.xht s71-abs-pos-non-replaced-vrl-096-ref.xht == 1183431-orthogonal-modes-1a.html 1183431-orthogonal-modes-1-ref.html == 1183431-orthogonal-modes-1b.html 1183431-orthogonal-modes-1-ref.html From 275c209d7d1354eba39228ac2a939a47e3160d45 Mon Sep 17 00:00:00 2001 From: "Dragana Damjanovic dd.mozilla@gmail.com" Date: Wed, 4 May 2016 01:29:00 -0400 Subject: [PATCH 15/56] Bug 1270029 - Set mSignaled only if PR_Write succeeds. r=mcmanus --HG-- extra : rebase_source : 43e7e5437728986c5c4c90c859b343467813b7b6 --- netwerk/base/PollableEvent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/netwerk/base/PollableEvent.cpp b/netwerk/base/PollableEvent.cpp index 40456481fab9..62d1d6231e3f 100644 --- a/netwerk/base/PollableEvent.cpp +++ b/netwerk/base/PollableEvent.cpp @@ -230,6 +230,7 @@ PollableEvent::Signal() if (status != 1) { NS_WARNING("PollableEvent::Signal Failed\n"); SOCKET_LOG(("PollableEvent::Signal Failed\n")); + mSignaled = false; } return (status == 1); } From 376575c614cf0d18ec99a4409e0ceecc882e6493 Mon Sep 17 00:00:00 2001 From: Mason Chang Date: Tue, 10 May 2016 08:00:06 -0700 Subject: [PATCH 16/56] Bug 1267260 - Change CanvasImageCache to lookup cache images based on imgIContainer instead of imgIRequest. r=seth --HG-- extra : rebase_source : 872ee783a05d0319ed69ce3c494dbf2a3206e26d --- dom/canvas/CanvasImageCache.cpp | 221 ++++++++++++++---------- dom/canvas/CanvasImageCache.h | 27 ++- dom/canvas/CanvasRenderingContext2D.cpp | 119 ++++++------- layout/base/nsLayoutUtils.cpp | 10 +- 4 files changed, 207 insertions(+), 170 deletions(-) diff --git a/dom/canvas/CanvasImageCache.cpp b/dom/canvas/CanvasImageCache.cpp index 260db515a569..465df072f102 100644 --- a/dom/canvas/CanvasImageCache.cpp +++ b/dom/canvas/CanvasImageCache.cpp @@ -20,60 +20,65 @@ namespace mozilla { using namespace dom; using namespace gfx; -struct ImageCacheKey { - ImageCacheKey(Element* aImage, +/** + * Used for images specific to this one canvas. Required + * due to CORS security. + */ +struct ImageCacheKey +{ + ImageCacheKey(imgIContainer* aImage, HTMLCanvasElement* aCanvas, bool aIsAccelerated) : mImage(aImage) , mCanvas(aCanvas) , mIsAccelerated(aIsAccelerated) {} - Element* mImage; + nsCOMPtr mImage; HTMLCanvasElement* mCanvas; bool mIsAccelerated; }; -struct ImageCacheEntryData { +/** + * Cache data needs to be separate from the entry + * for nsExpirationTracker. + */ +struct ImageCacheEntryData +{ ImageCacheEntryData(const ImageCacheEntryData& aOther) : mImage(aOther.mImage) - , mILC(aOther.mILC) , mCanvas(aOther.mCanvas) , mIsAccelerated(aOther.mIsAccelerated) - , mRequest(aOther.mRequest) , mSourceSurface(aOther.mSourceSurface) , mSize(aOther.mSize) {} explicit ImageCacheEntryData(const ImageCacheKey& aKey) : mImage(aKey.mImage) - , mILC(nullptr) , mCanvas(aKey.mCanvas) , mIsAccelerated(aKey.mIsAccelerated) {} nsExpirationState* GetExpirationState() { return &mState; } - size_t SizeInBytes() { return mSize.width * mSize.height * 4; } // Key - RefPtr mImage; - nsIImageLoadingContent* mILC; - RefPtr mCanvas; + nsCOMPtr mImage; + HTMLCanvasElement* mCanvas; bool mIsAccelerated; // Value - nsCOMPtr mRequest; RefPtr mSourceSurface; IntSize mSize; nsExpirationState mState; }; -class ImageCacheEntry : public PLDHashEntryHdr { +class ImageCacheEntry : public PLDHashEntryHdr +{ public: typedef ImageCacheKey KeyType; typedef const ImageCacheKey* KeyTypePointer; explicit ImageCacheEntry(const KeyType* aKey) : mData(new ImageCacheEntryData(*aKey)) {} - ImageCacheEntry(const ImageCacheEntry &toCopy) : + ImageCacheEntry(const ImageCacheEntry& toCopy) : mData(new ImageCacheEntryData(*toCopy.mData)) {} ~ImageCacheEntry() {} @@ -87,52 +92,61 @@ public: static KeyTypePointer KeyToPointer(KeyType& key) { return &key; } static PLDHashNumber HashKey(KeyTypePointer key) { - return HashGeneric(key->mImage, key->mCanvas, key->mIsAccelerated); + return HashGeneric(key->mImage.get(), key->mCanvas, key->mIsAccelerated); } enum { ALLOW_MEMMOVE = true }; nsAutoPtr mData; }; -struct SimpleImageCacheKey { - SimpleImageCacheKey(const imgIRequest* aImage, - bool aIsAccelerated) + +/** + * Used for all images across all canvases. + */ +struct AllCanvasImageCacheKey +{ + AllCanvasImageCacheKey(imgIContainer* aImage, + bool aIsAccelerated) : mImage(aImage) , mIsAccelerated(aIsAccelerated) {} - const imgIRequest* mImage; + + nsCOMPtr mImage; bool mIsAccelerated; }; -class SimpleImageCacheEntry : public PLDHashEntryHdr { +class AllCanvasImageCacheEntry : public PLDHashEntryHdr { public: - typedef SimpleImageCacheKey KeyType; - typedef const SimpleImageCacheKey* KeyTypePointer; + typedef AllCanvasImageCacheKey KeyType; + typedef const AllCanvasImageCacheKey* KeyTypePointer; - explicit SimpleImageCacheEntry(KeyTypePointer aKey) - : mRequest(const_cast(aKey->mImage)) + explicit AllCanvasImageCacheEntry(const KeyType* aKey) + : mImage(aKey->mImage) , mIsAccelerated(aKey->mIsAccelerated) {} - SimpleImageCacheEntry(const SimpleImageCacheEntry &toCopy) - : mRequest(toCopy.mRequest) + + AllCanvasImageCacheEntry(const AllCanvasImageCacheEntry &toCopy) + : mImage(toCopy.mImage) , mIsAccelerated(toCopy.mIsAccelerated) , mSourceSurface(toCopy.mSourceSurface) {} - ~SimpleImageCacheEntry() {} + + ~AllCanvasImageCacheEntry() {} bool KeyEquals(KeyTypePointer key) const { - return key->mImage == mRequest && key->mIsAccelerated == mIsAccelerated; + return mImage == key->mImage && + mIsAccelerated == key->mIsAccelerated; } static KeyTypePointer KeyToPointer(KeyType& key) { return &key; } static PLDHashNumber HashKey(KeyTypePointer key) { - return HashGeneric(key->mImage, key->mIsAccelerated); + return HashGeneric(key->mImage.get(), key->mIsAccelerated); } enum { ALLOW_MEMMOVE = true }; - nsCOMPtr mRequest; + nsCOMPtr mImage; bool mIsAccelerated; RefPtr mSourceSurface; }; @@ -142,7 +156,8 @@ static int32_t sCanvasImageCacheLimit = 0; class ImageCacheObserver; -class ImageCache final : public nsExpirationTracker { +class ImageCache final : public nsExpirationTracker +{ public: // We use 3 generations of 1 second each to get a 2-3 seconds timeout. enum { GENERATION_MS = 1000 }; @@ -153,20 +168,24 @@ public: { mTotal -= aObject->SizeInBytes(); RemoveObject(aObject); - // Deleting the entry will delete aObject since the entry owns aObject - mSimpleCache.RemoveEntry(SimpleImageCacheKey(aObject->mRequest, aObject->mIsAccelerated)); + + // Remove from the all canvas cache entry first since nsExpirationTracker + // will delete aObject. + mAllCanvasCache.RemoveEntry(AllCanvasImageCacheKey(aObject->mImage, aObject->mIsAccelerated)); + + // Deleting the entry will delete aObject since the entry owns aObject. mCache.RemoveEntry(ImageCacheKey(aObject->mImage, aObject->mCanvas, aObject->mIsAccelerated)); } nsTHashtable mCache; - nsTHashtable mSimpleCache; + nsTHashtable mAllCanvasCache; size_t mTotal; RefPtr mImageCacheObserver; }; static ImageCache* gImageCache = nullptr; -// Listen memory-pressure event for image cache purge +// Listen memory-pressure event for image cache purge. class ImageCacheObserver final : public nsIObserver { public: @@ -256,10 +275,33 @@ ImageCache::~ImageCache() { mImageCacheObserver->Destroy(); } +static already_AddRefed +GetImageContainer(dom::Element* aImage) +{ + nsCOMPtr request; + nsCOMPtr ilc = do_QueryInterface(aImage); + if (!ilc) { + return nullptr; + } + + ilc->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, + getter_AddRefs(request)); + if (!request) { + return nullptr; + } + + nsCOMPtr imgContainer; + request->GetImage(getter_AddRefs(imgContainer)); + if (!imgContainer) { + return nullptr; + } + + return imgContainer.forget(); +} + void CanvasImageCache::NotifyDrawImage(Element* aImage, HTMLCanvasElement* aCanvas, - imgIRequest* aRequest, SourceSurface* aSource, const IntSize& aSize, bool aIsAccelerated) @@ -269,32 +311,31 @@ CanvasImageCache::NotifyDrawImage(Element* aImage, nsContentUtils::RegisterShutdownObserver(new CanvasImageCacheShutdownObserver()); } - ImageCacheEntry* entry = - gImageCache->mCache.PutEntry(ImageCacheKey(aImage, aCanvas, aIsAccelerated)); + nsCOMPtr imgContainer = GetImageContainer(aImage); + if (!imgContainer) { + return; + } + + AllCanvasImageCacheKey allCanvasCacheKey(imgContainer, aIsAccelerated); + ImageCacheKey canvasCacheKey(imgContainer, aCanvas, aIsAccelerated); + ImageCacheEntry* entry = gImageCache->mCache.PutEntry(canvasCacheKey); + if (entry) { if (entry->mData->mSourceSurface) { // We are overwriting an existing entry. gImageCache->mTotal -= entry->mData->SizeInBytes(); gImageCache->RemoveObject(entry->mData); - gImageCache->mSimpleCache.RemoveEntry(SimpleImageCacheKey(entry->mData->mRequest, entry->mData->mIsAccelerated)); + gImageCache->mAllCanvasCache.RemoveEntry(allCanvasCacheKey); } - gImageCache->AddObject(entry->mData); - nsCOMPtr ilc = do_QueryInterface(aImage); - if (ilc) { - ilc->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, - getter_AddRefs(entry->mData->mRequest)); - } - entry->mData->mILC = ilc; + gImageCache->AddObject(entry->mData); entry->mData->mSourceSurface = aSource; entry->mData->mSize = aSize; - gImageCache->mTotal += entry->mData->SizeInBytes(); - if (entry->mData->mRequest) { - SimpleImageCacheEntry* simpleentry = - gImageCache->mSimpleCache.PutEntry(SimpleImageCacheKey(entry->mData->mRequest, aIsAccelerated)); - simpleentry->mSourceSurface = aSource; + AllCanvasImageCacheEntry* allEntry = gImageCache->mAllCanvasCache.PutEntry(allCanvasCacheKey); + if (allEntry) { + allEntry->mSourceSurface = aSource; } } @@ -307,54 +348,56 @@ CanvasImageCache::NotifyDrawImage(Element* aImage, } SourceSurface* -CanvasImageCache::Lookup(Element* aImage, - HTMLCanvasElement* aCanvas, - gfx::IntSize* aSize, - bool aIsAccelerated) +CanvasImageCache::LookupAllCanvas(Element* aImage, + bool aIsAccelerated) { - if (!gImageCache) + if (!gImageCache) { return nullptr; + } - ImageCacheEntry* entry = - gImageCache->mCache.GetEntry(ImageCacheKey(aImage, aCanvas, aIsAccelerated)); - if (!entry || !entry->mData->mILC) + nsCOMPtr imgContainer = GetImageContainer(aImage); + if (!imgContainer) { return nullptr; + } - nsCOMPtr request; - entry->mData->mILC->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, getter_AddRefs(request)); - if (request != entry->mData->mRequest) - return nullptr; - - gImageCache->MarkUsed(entry->mData); - - *aSize = entry->mData->mSize; - return entry->mData->mSourceSurface; -} - -SourceSurface* -CanvasImageCache::SimpleLookup(Element* aImage, - bool aIsAccelerated) -{ - if (!gImageCache) - return nullptr; - - nsCOMPtr request; - nsCOMPtr ilc = do_QueryInterface(aImage); - if (!ilc) - return nullptr; - - ilc->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, - getter_AddRefs(request)); - if (!request) - return nullptr; - - SimpleImageCacheEntry* entry = gImageCache->mSimpleCache.GetEntry(SimpleImageCacheKey(request, aIsAccelerated)); - if (!entry) + AllCanvasImageCacheEntry* entry = + gImageCache->mAllCanvasCache.GetEntry(AllCanvasImageCacheKey(imgContainer, aIsAccelerated)); + if (!entry) { return nullptr; + } return entry->mSourceSurface; } +SourceSurface* +CanvasImageCache::LookupCanvas(Element* aImage, + HTMLCanvasElement* aCanvas, + IntSize* aSizeOut, + bool aIsAccelerated) +{ + if (!gImageCache) { + return nullptr; + } + + nsCOMPtr imgContainer = GetImageContainer(aImage); + if (!imgContainer) { + return nullptr; + } + + ImageCacheEntry* entry = + gImageCache->mCache.GetEntry(ImageCacheKey(imgContainer, aCanvas, aIsAccelerated)); + if (!entry) { + return nullptr; + } + + MOZ_ASSERT(aSizeOut); + + gImageCache->MarkUsed(entry->mData); + *aSizeOut = entry->mData->mSize; + return entry->mData->mSourceSurface; +} + + NS_IMPL_ISUPPORTS(CanvasImageCacheShutdownObserver, nsIObserver) NS_IMETHODIMP diff --git a/dom/canvas/CanvasImageCache.h b/dom/canvas/CanvasImageCache.h index ca38818801d5..f537067ec540 100644 --- a/dom/canvas/CanvasImageCache.h +++ b/dom/canvas/CanvasImageCache.h @@ -6,6 +6,7 @@ #ifndef CANVASIMAGECACHE_H_ #define CANVASIMAGECACHE_H_ +#include "mozilla/RefPtr.h" #include "nsSize.h" namespace mozilla { @@ -17,7 +18,7 @@ namespace gfx { class SourceSurface; } // namespace gfx } // namespace mozilla -class imgIRequest; +class imgIContainer; namespace mozilla { @@ -25,34 +26,30 @@ class CanvasImageCache { typedef mozilla::gfx::SourceSurface SourceSurface; public: /** - * Notify that image element aImage was (or is about to be) drawn to aCanvas + * Notify that image element aImage was drawn to aCanvas element * using the first frame of aRequest's image. The data for the surface is * in aSurface, and the image size is in aSize. */ static void NotifyDrawImage(dom::Element* aImage, dom::HTMLCanvasElement* aCanvas, - imgIRequest* aRequest, SourceSurface* aSource, const gfx::IntSize& aSize, bool aIsAccelerated); /** - * Check whether aImage has recently been drawn into aCanvas. If we return - * a non-null surface, then the image was recently drawn into the canvas - * (with the same image request) and the returned surface contains the image - * data, and the image size will be returned in aSize. + * Check whether aImage has recently been drawn any canvas. If we return + * a non-null surface, then the same image was recently drawn into a canvas. */ - static SourceSurface* Lookup(dom::Element* aImage, - dom::HTMLCanvasElement* aCanvas, - gfx::IntSize* aSize, - bool aIsAccelerated); + static SourceSurface* LookupAllCanvas(dom::Element* aImage, + bool aIsAccelerated); /** - * This is the same as Lookup, except it works on any image recently drawn - * into any canvas. Security checks need to be done again if using the - * results from this. + * Like the top above, but restricts the lookup to only aCanvas. This is + * required for CORS security. */ - static SourceSurface* SimpleLookup(dom::Element* aImage, + static SourceSurface* LookupCanvas(dom::Element* aImage, + dom::HTMLCanvasElement* aCanvas, + gfx::IntSize* aSizeOut, bool aIsAccelerated); }; diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 937097159a1a..16b26aaa7723 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -4361,57 +4361,6 @@ ExtractSubrect(SourceSurface* aSurface, gfx::Rect* aSourceRect, DrawTarget* aTar return subrectDT->Snapshot(); } -// Acts like nsLayoutUtils::SurfaceFromElement, but it'll attempt -// to pull a SourceSurface from our cache. This allows us to avoid -// reoptimizing surfaces if content and canvas backends are different. -nsLayoutUtils::SurfaceFromElementResult -CanvasRenderingContext2D::CachedSurfaceFromElement(Element* aElement) -{ - nsLayoutUtils::SurfaceFromElementResult res; - - nsCOMPtr imageLoader = do_QueryInterface(aElement); - if (!imageLoader) { - return res; - } - - nsCOMPtr imgRequest; - imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, - getter_AddRefs(imgRequest)); - if (!imgRequest) { - return res; - } - - uint32_t status; - if (NS_FAILED(imgRequest->GetImageStatus(&status)) || - !(status & imgIRequest::STATUS_LOAD_COMPLETE)) { - return res; - } - - nsCOMPtr principal; - if (NS_FAILED(imgRequest->GetImagePrincipal(getter_AddRefs(principal))) || - !principal) { - return res; - } - - res.mSourceSurface = - CanvasImageCache::SimpleLookup(aElement, mIsSkiaGL); - if (!res.mSourceSurface) { - return res; - } - - int32_t corsmode = imgIRequest::CORS_NONE; - if (NS_SUCCEEDED(imgRequest->GetCORSMode(&corsmode))) { - res.mCORSUsed = corsmode != imgIRequest::CORS_NONE; - } - - res.mSize = res.mSourceSurface->GetSize(); - res.mPrincipal = principal.forget(); - res.mIsWriteOnly = false; - res.mImageRequest = imgRequest.forget(); - - return res; -} - // // image // @@ -4435,6 +4384,56 @@ ClipImageDimension(double& aSourceCoord, double& aSourceSize, int32_t aImageSize } } +// Acts like nsLayoutUtils::SurfaceFromElement, but it'll attempt +// to pull a SourceSurface from our cache. This allows us to avoid +// reoptimizing surfaces if content and canvas backends are different. +nsLayoutUtils::SurfaceFromElementResult +CanvasRenderingContext2D::CachedSurfaceFromElement(Element* aElement) +{ + nsLayoutUtils::SurfaceFromElementResult res; + nsCOMPtr imageLoader = do_QueryInterface(aElement); + if (!imageLoader) { + return res; + } + + nsCOMPtr imgRequest; + imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, + getter_AddRefs(imgRequest)); + if (!imgRequest) { + return res; + } + + uint32_t status = 0; + if (NS_FAILED(imgRequest->GetImageStatus(&status)) || + !(status & imgIRequest::STATUS_LOAD_COMPLETE)) { + return res; + } + + nsCOMPtr principal; + if (NS_FAILED(imgRequest->GetImagePrincipal(getter_AddRefs(principal))) || + !principal) { + return res; + } + + res.mSourceSurface = + CanvasImageCache::LookupAllCanvas(aElement, mIsSkiaGL); + if (!res.mSourceSurface) { + return res; + } + + int32_t corsmode = imgIRequest::CORS_NONE; + if (NS_SUCCEEDED(imgRequest->GetCORSMode(&corsmode))) { + res.mCORSUsed = corsmode != imgIRequest::CORS_NONE; + } + + res.mSize = res.mSourceSurface->GetSize(); + res.mPrincipal = principal.forget(); + res.mIsWriteOnly = false; + res.mImageRequest = imgRequest.forget(); + + return res; +} + // drawImage(in HTMLImageElement image, in float dx, in float dy); // -- render image from 0,0 at dx,dy top-left coords // drawImage(in HTMLImageElement image, in float dx, in float dy, in float dw, in float dh); @@ -4504,7 +4503,7 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage, } srcSurf = - CanvasImageCache::Lookup(element, mCanvasElement, &imgSize, mIsSkiaGL); + CanvasImageCache::LookupCanvas(element, mCanvasElement, &imgSize, mIsSkiaGL); } nsLayoutUtils::DirectDrawInfo drawInfo; @@ -4613,15 +4612,13 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage, // of animated images. We also don't want to rasterize vector images. uint32_t sfeFlags = nsLayoutUtils::SFE_WANT_FIRST_FRAME | nsLayoutUtils::SFE_NO_RASTERIZING_VECTORS; - // The cache lookup can miss even if the image is already in the cache - // if the image is coming from a different element or cached for a - // different canvas. This covers the case when we miss due to caching - // for a different canvas, but CanvasImageCache should be fixed if we - // see misses due to different elements drawing the same image. + nsLayoutUtils::SurfaceFromElementResult res = - CachedSurfaceFromElement(element); - if (!res.mSourceSurface) + CanvasRenderingContext2D::CachedSurfaceFromElement(element); + + if (!res.mSourceSurface) { res = nsLayoutUtils::SurfaceFromElement(element, sfeFlags, mTarget); + } if (!res.mSourceSurface && !res.mDrawInfo.mImgContainer) { // The spec says to silently do nothing in the following cases: @@ -4653,10 +4650,8 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage, if (res.mSourceSurface) { if (res.mImageRequest) { - CanvasImageCache::NotifyDrawImage(element, mCanvasElement, res.mImageRequest, - res.mSourceSurface, imgSize, mIsSkiaGL); + CanvasImageCache::NotifyDrawImage(element, mCanvasElement, res.mSourceSurface, imgSize, mIsSkiaGL); } - srcSurf = res.mSourceSurface; } else { drawInfo = res.mDrawInfo; diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index b4579f791c11..428817ef356b 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -7281,8 +7281,9 @@ nsLayoutUtils::SurfaceFromElement(nsIImageLoadingContent* aElement, nsCOMPtr imgRequest; rv = aElement->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, getter_AddRefs(imgRequest)); - if (NS_FAILED(rv) || !imgRequest) + if (NS_FAILED(rv) || !imgRequest) { return result; + } uint32_t status; imgRequest->GetImageStatus(&status); @@ -7297,13 +7298,15 @@ nsLayoutUtils::SurfaceFromElement(nsIImageLoadingContent* aElement, nsCOMPtr principal; rv = imgRequest->GetImagePrincipal(getter_AddRefs(principal)); - if (NS_FAILED(rv)) + if (NS_FAILED(rv)) { return result; + } nsCOMPtr imgContainer; rv = imgRequest->GetImage(getter_AddRefs(imgContainer)); - if (NS_FAILED(rv)) + if (NS_FAILED(rv)) { return result; + } uint32_t noRasterize = aSurfaceFlags & SFE_NO_RASTERIZING_VECTORS; @@ -7368,7 +7371,6 @@ nsLayoutUtils::SurfaceFromElement(nsIImageLoadingContent* aElement, // no images, including SVG images, can load content from another domain. result.mIsWriteOnly = false; result.mImageRequest = imgRequest.forget(); - return result; } From 4fcf10742d2c51442ab123ed1508d27cec106db4 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Tue, 10 May 2016 16:43:17 -0700 Subject: [PATCH 17/56] Bug 1271493 Dispatch fetch control runnable even in opt builds. r=mccr8 --- dom/fetch/Fetch.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp index 920c7bd45c71..9b2655a7af91 100644 --- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -335,7 +335,7 @@ public: return true; } - nsresult + NS_IMETHOD Cancel() override { // Execute Run anyway to make sure we cleanup our promise proxy to avoid @@ -403,8 +403,9 @@ WorkerFetchResolver::OnResponseEnd() // This can fail if the worker thread is canceled or killed causing // the PromiseWorkerProxy to give up its WorkerFeature immediately, // allowing the worker thread to become Dead. - NS_WARN_IF_FALSE(cr->Dispatch(), - "Failed to dispatch WorkerFetchResponseEndControlRunnable"); + if (!cr->Dispatch()) { + NS_WARNING("Failed to dispatch WorkerFetchResponseEndControlRunnable"); + } } } From 03cb039b4e93691d30ab4695938cda80c0a00144 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 10 May 2016 17:59:21 -0400 Subject: [PATCH 18/56] Bug 1271784. Allow WARP WebGL on Windows 7 without SP 1 r=jgilbert ANGLE doesn't allow WARP on DXGI < 1.2 by default, but it will work fine for us. --- gfx/angle/moz.build | 1 + gfx/angle/src/commit.h | 4 ++-- gfx/angle/src/libANGLE/moz.build | 1 + gfx/angle/src/libEGL/moz.build | 1 + gfx/angle/src/libGLESv2/moz.build | 1 + 5 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gfx/angle/moz.build b/gfx/angle/moz.build index 49f681ffc5c4..663627b1a1fd 100644 --- a/gfx/angle/moz.build +++ b/gfx/angle/moz.build @@ -138,6 +138,7 @@ if not CONFIG['MOZ_DEBUG']: DEFINES['_SECURE_SCL'] = 0 DEFINES['ANGLE_ENABLE_D3D9'] = True +DEFINES['ANGLE_SKIP_DXGI_1_2_CHECK'] = True if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']: DEFINES['ANGLE_ENABLE_D3D11'] = True diff --git a/gfx/angle/src/commit.h b/gfx/angle/src/commit.h index 12ca80c7c5f5..0a372d999807 100644 --- a/gfx/angle/src/commit.h +++ b/gfx/angle/src/commit.h @@ -1,3 +1,3 @@ -#define ANGLE_COMMIT_HASH "f1101625dbbe" +#define ANGLE_COMMIT_HASH "0ed5ff9d075e" #define ANGLE_COMMIT_HASH_SIZE 12 -#define ANGLE_COMMIT_DATE "2016-02-24 21:04:03 -0500" +#define ANGLE_COMMIT_DATE "2016-04-29 17:26:19 -0400" diff --git a/gfx/angle/src/libANGLE/moz.build b/gfx/angle/src/libANGLE/moz.build index 6d8275c32436..153a8a9b862e 100644 --- a/gfx/angle/src/libANGLE/moz.build +++ b/gfx/angle/src/libANGLE/moz.build @@ -292,6 +292,7 @@ if not CONFIG['MOZ_DEBUG']: DEFINES['_SECURE_SCL'] = 0 DEFINES['ANGLE_ENABLE_D3D9'] = True +DEFINES['ANGLE_SKIP_DXGI_1_2_CHECK'] = True if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']: DEFINES['ANGLE_ENABLE_D3D11'] = True diff --git a/gfx/angle/src/libEGL/moz.build b/gfx/angle/src/libEGL/moz.build index 4000b964e975..8e99d44ff713 100644 --- a/gfx/angle/src/libEGL/moz.build +++ b/gfx/angle/src/libEGL/moz.build @@ -42,6 +42,7 @@ if not CONFIG['MOZ_DEBUG']: DEFINES['_SECURE_SCL'] = 0 DEFINES['ANGLE_ENABLE_D3D9'] = True +DEFINES['ANGLE_SKIP_DXGI_1_2_CHECK'] = True if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']: DEFINES['ANGLE_ENABLE_D3D11'] = True diff --git a/gfx/angle/src/libGLESv2/moz.build b/gfx/angle/src/libGLESv2/moz.build index 404408d45536..a004425d873a 100644 --- a/gfx/angle/src/libGLESv2/moz.build +++ b/gfx/angle/src/libGLESv2/moz.build @@ -48,6 +48,7 @@ if not CONFIG['MOZ_DEBUG']: DEFINES['_SECURE_SCL'] = 0 DEFINES['ANGLE_ENABLE_D3D9'] = True +DEFINES['ANGLE_SKIP_DXGI_1_2_CHECK'] = True if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']: DEFINES['ANGLE_ENABLE_D3D11'] = True From 45e57962487c91dd00cb2ba8f80ae5108ffc6c0b Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Tue, 10 May 2016 17:38:39 -0700 Subject: [PATCH 19/56] Backout 212d1af61570 (bug 1271493) for winxp bustage. r=me --- dom/fetch/Fetch.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp index 9b2655a7af91..920c7bd45c71 100644 --- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -335,7 +335,7 @@ public: return true; } - NS_IMETHOD + nsresult Cancel() override { // Execute Run anyway to make sure we cleanup our promise proxy to avoid @@ -403,9 +403,8 @@ WorkerFetchResolver::OnResponseEnd() // This can fail if the worker thread is canceled or killed causing // the PromiseWorkerProxy to give up its WorkerFeature immediately, // allowing the worker thread to become Dead. - if (!cr->Dispatch()) { - NS_WARNING("Failed to dispatch WorkerFetchResponseEndControlRunnable"); - } + NS_WARN_IF_FALSE(cr->Dispatch(), + "Failed to dispatch WorkerFetchResponseEndControlRunnable"); } } From 6d65ee672ed28ac6a1f3bafec0a5a13268ef9e6f Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Wed, 11 May 2016 09:54:41 +0900 Subject: [PATCH 20/56] Bug 1271037 - Part 1: Fix numOperands of RRegExpMatcher, RRegExpSearcher, and RRegExpTester. r=h4writer, a=abillings --- js/src/jit/Recover.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/src/jit/Recover.h b/js/src/jit/Recover.h index 3285f23aaf3e..6de9272d520a 100644 --- a/js/src/jit/Recover.h +++ b/js/src/jit/Recover.h @@ -565,7 +565,7 @@ class RRegExpMatcher final : public RInstruction RINSTRUCTION_HEADER_(RegExpMatcher) virtual uint32_t numOperands() const { - return 5; + return 3; } bool recover(JSContext* cx, SnapshotIterator& iter) const; @@ -577,7 +577,7 @@ class RRegExpSearcher final : public RInstruction RINSTRUCTION_HEADER_(RegExpSearcher) virtual uint32_t numOperands() const { - return 5; + return 3; } bool recover(JSContext* cx, SnapshotIterator& iter) const; @@ -589,7 +589,7 @@ class RRegExpTester final : public RInstruction RINSTRUCTION_HEADER_(RegExpTester) virtual uint32_t numOperands() const { - return 5; + return 3; } bool recover(JSContext* cx, SnapshotIterator& iter) const; From ea623b4b418cbf15a84fc89a4c9764b47c3f7510 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Wed, 11 May 2016 09:54:42 +0900 Subject: [PATCH 21/56] Bug 1271037 - Part 2: Statically check that numOperands of the recover instruction and the MIR are consistent. r=h4writer, a=abillings --- js/src/jit/MIR.h | 3 + js/src/jit/Recover.h | 287 ++++++++++--------------------------------- 2 files changed, 65 insertions(+), 225 deletions(-) diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index d574a1e7beb0..c2c37c63cae9 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -1115,6 +1115,9 @@ class MAryInstruction : public MInstruction size_t numOperands() const final override { return Arity; } +#ifdef DEBUG + static const size_t staticNumOperands = Arity; +#endif size_t indexOf(const MUse* u) const final override { MOZ_ASSERT(u >= &operands_[0]); MOZ_ASSERT(u <= &operands_[numOperands() - 1]); diff --git a/js/src/jit/Recover.h b/js/src/jit/Recover.h index 6de9272d520a..0e231b9c91f4 100644 --- a/js/src/jit/Recover.h +++ b/js/src/jit/Recover.h @@ -155,6 +155,21 @@ class RInstruction return RInstruction::Recover_##op; \ } +#define RINSTRUCTION_HEADER_NUM_OP_MAIN(op, numOp) \ + RINSTRUCTION_HEADER_(op) \ + virtual uint32_t numOperands() const { \ + return numOp; \ + } + +#ifdef DEBUG +# define RINSTRUCTION_HEADER_NUM_OP_(op, numOp) \ + RINSTRUCTION_HEADER_NUM_OP_MAIN(op, numOp) \ + static_assert(M##op::staticNumOperands == numOp, "The recover instructions's numOperands should equal to the MIR's numOperands"); +#else +# define RINSTRUCTION_HEADER_NUM_OP_(op, numOp) \ + RINSTRUCTION_HEADER_NUM_OP_MAIN(op, numOp) +#endif + class RResumePoint final : public RInstruction { private: @@ -176,11 +191,7 @@ class RResumePoint final : public RInstruction class RBitNot final : public RInstruction { public: - RINSTRUCTION_HEADER_(BitNot) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(BitNot, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -188,11 +199,7 @@ class RBitNot final : public RInstruction class RBitAnd final : public RInstruction { public: - RINSTRUCTION_HEADER_(BitAnd) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(BitAnd, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -200,11 +207,7 @@ class RBitAnd final : public RInstruction class RBitOr final : public RInstruction { public: - RINSTRUCTION_HEADER_(BitOr) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(BitOr, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -212,11 +215,7 @@ class RBitOr final : public RInstruction class RBitXor final : public RInstruction { public: - RINSTRUCTION_HEADER_(BitXor) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(BitXor, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -224,11 +223,7 @@ class RBitXor final : public RInstruction class RLsh final : public RInstruction { public: - RINSTRUCTION_HEADER_(Lsh) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(Lsh, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -236,11 +231,7 @@ class RLsh final : public RInstruction class RRsh final : public RInstruction { public: - RINSTRUCTION_HEADER_(Rsh) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(Rsh, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -248,11 +239,7 @@ class RRsh final : public RInstruction class RUrsh final : public RInstruction { public: - RINSTRUCTION_HEADER_(Ursh) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(Ursh, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -263,11 +250,7 @@ class RAdd final : public RInstruction bool isFloatOperation_; public: - RINSTRUCTION_HEADER_(Add) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(Add, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -278,11 +261,7 @@ class RSub final : public RInstruction bool isFloatOperation_; public: - RINSTRUCTION_HEADER_(Sub) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(Sub, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -294,11 +273,7 @@ class RMul final : public RInstruction uint8_t mode_; public: - RINSTRUCTION_HEADER_(Mul) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(Mul, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -309,11 +284,7 @@ class RDiv final : public RInstruction bool isFloatOperation_; public: - RINSTRUCTION_HEADER_(Div) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(Div, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -321,11 +292,7 @@ class RDiv final : public RInstruction class RMod final : public RInstruction { public: - RINSTRUCTION_HEADER_(Mod) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(Mod, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -333,11 +300,7 @@ class RMod final : public RInstruction class RNot final : public RInstruction { public: - RINSTRUCTION_HEADER_(Not) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(Not, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -345,11 +308,7 @@ class RNot final : public RInstruction class RConcat final : public RInstruction { public: - RINSTRUCTION_HEADER_(Concat) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(Concat, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -357,11 +316,7 @@ class RConcat final : public RInstruction class RStringLength final : public RInstruction { public: - RINSTRUCTION_HEADER_(StringLength) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(StringLength, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -369,11 +324,7 @@ class RStringLength final : public RInstruction class RArgumentsLength final : public RInstruction { public: - RINSTRUCTION_HEADER_(ArgumentsLength) - - virtual uint32_t numOperands() const { - return 0; - } + RINSTRUCTION_HEADER_NUM_OP_(ArgumentsLength, 0) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -382,11 +333,7 @@ class RArgumentsLength final : public RInstruction class RFloor final : public RInstruction { public: - RINSTRUCTION_HEADER_(Floor) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(Floor, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -394,11 +341,7 @@ class RFloor final : public RInstruction class RCeil final : public RInstruction { public: - RINSTRUCTION_HEADER_(Ceil) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(Ceil, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -406,11 +349,7 @@ class RCeil final : public RInstruction class RRound final : public RInstruction { public: - RINSTRUCTION_HEADER_(Round) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(Round, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -418,11 +357,7 @@ class RRound final : public RInstruction class RCharCodeAt final : public RInstruction { public: - RINSTRUCTION_HEADER_(CharCodeAt) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(CharCodeAt, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -430,11 +365,7 @@ class RCharCodeAt final : public RInstruction class RFromCharCode final : public RInstruction { public: - RINSTRUCTION_HEADER_(FromCharCode) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(FromCharCode, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -442,11 +373,7 @@ class RFromCharCode final : public RInstruction class RPow final : public RInstruction { public: - RINSTRUCTION_HEADER_(Pow) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(Pow, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -454,11 +381,7 @@ class RPow final : public RInstruction class RPowHalf final : public RInstruction { public: - RINSTRUCTION_HEADER_(PowHalf) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(PowHalf, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -469,11 +392,7 @@ class RMinMax final : public RInstruction bool isMax_; public: - RINSTRUCTION_HEADER_(MinMax) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(MinMax, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -481,11 +400,7 @@ class RMinMax final : public RInstruction class RAbs final : public RInstruction { public: - RINSTRUCTION_HEADER_(Abs) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(Abs, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -496,11 +411,7 @@ class RSqrt final : public RInstruction bool isFloatOperation_; public: - RINSTRUCTION_HEADER_(Sqrt) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(Sqrt, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -508,11 +419,7 @@ class RSqrt final : public RInstruction class RAtan2 final : public RInstruction { public: - RINSTRUCTION_HEADER_(Atan2) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(Atan2, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -538,11 +445,7 @@ class RMathFunction final : public RInstruction uint8_t function_; public: - RINSTRUCTION_HEADER_(MathFunction) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(MathFunction, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -550,11 +453,7 @@ class RMathFunction final : public RInstruction class RStringSplit final : public RInstruction { public: - RINSTRUCTION_HEADER_(StringSplit) - - virtual uint32_t numOperands() const { - return 3; - } + RINSTRUCTION_HEADER_NUM_OP_(StringSplit, 3) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -562,11 +461,7 @@ class RStringSplit final : public RInstruction class RRegExpMatcher final : public RInstruction { public: - RINSTRUCTION_HEADER_(RegExpMatcher) - - virtual uint32_t numOperands() const { - return 3; - } + RINSTRUCTION_HEADER_NUM_OP_(RegExpMatcher, 3) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -574,11 +469,7 @@ class RRegExpMatcher final : public RInstruction class RRegExpSearcher final : public RInstruction { public: - RINSTRUCTION_HEADER_(RegExpSearcher) - - virtual uint32_t numOperands() const { - return 3; - } + RINSTRUCTION_HEADER_NUM_OP_(RegExpSearcher, 3) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -586,11 +477,7 @@ class RRegExpSearcher final : public RInstruction class RRegExpTester final : public RInstruction { public: - RINSTRUCTION_HEADER_(RegExpTester) - - virtual uint32_t numOperands() const { - return 3; - } + RINSTRUCTION_HEADER_NUM_OP_(RegExpTester, 3) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -601,11 +488,7 @@ class RStringReplace final : public RInstruction bool isFlatReplacement_; public: - RINSTRUCTION_HEADER_(StringReplace) - - virtual uint32_t numOperands() const { - return 3; - } + RINSTRUCTION_HEADER_NUM_OP_(StringReplace, 3) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -613,11 +496,7 @@ class RStringReplace final : public RInstruction class RTypeOf final : public RInstruction { public: - RINSTRUCTION_HEADER_(TypeOf) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(TypeOf, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -625,11 +504,7 @@ class RTypeOf final : public RInstruction class RToDouble final : public RInstruction { public: - RINSTRUCTION_HEADER_(ToDouble) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(ToDouble, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -637,11 +512,7 @@ class RToDouble final : public RInstruction class RToFloat32 final : public RInstruction { public: - RINSTRUCTION_HEADER_(ToFloat32) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(ToFloat32, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -649,11 +520,7 @@ class RToFloat32 final : public RInstruction class RTruncateToInt32 final : public RInstruction { public: - RINSTRUCTION_HEADER_(TruncateToInt32) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(TruncateToInt32, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -664,11 +531,7 @@ class RNewObject final : public RInstruction MNewObject::Mode mode_; public: - RINSTRUCTION_HEADER_(NewObject) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(NewObject, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -679,11 +542,7 @@ class RNewArray final : public RInstruction uint32_t count_; public: - RINSTRUCTION_HEADER_(NewArray) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(NewArray, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -691,11 +550,7 @@ class RNewArray final : public RInstruction class RNewDerivedTypedObject final : public RInstruction { public: - RINSTRUCTION_HEADER_(NewDerivedTypedObject) - - virtual uint32_t numOperands() const { - return 3; - } + RINSTRUCTION_HEADER_NUM_OP_(NewDerivedTypedObject, 3) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -703,11 +558,7 @@ class RNewDerivedTypedObject final : public RInstruction class RCreateThisWithTemplate final : public RInstruction { public: - RINSTRUCTION_HEADER_(CreateThisWithTemplate) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(CreateThisWithTemplate, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -715,11 +566,7 @@ class RCreateThisWithTemplate final : public RInstruction class RLambda final : public RInstruction { public: - RINSTRUCTION_HEADER_(Lambda) - - virtual uint32_t numOperands() const { - return 2; - } + RINSTRUCTION_HEADER_NUM_OP_(Lambda, 2) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -730,11 +577,7 @@ class RSimdBox final : public RInstruction uint8_t type_; public: - RINSTRUCTION_HEADER_(SimdBox) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(SimdBox, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -781,11 +624,7 @@ class RArrayState final : public RInstruction class RAtomicIsLockFree final : public RInstruction { public: - RINSTRUCTION_HEADER_(AtomicIsLockFree) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(AtomicIsLockFree, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; @@ -793,16 +632,14 @@ class RAtomicIsLockFree final : public RInstruction class RAssertRecoveredOnBailout final : public RInstruction { public: - RINSTRUCTION_HEADER_(AssertRecoveredOnBailout) - - virtual uint32_t numOperands() const { - return 1; - } + RINSTRUCTION_HEADER_NUM_OP_(AssertRecoveredOnBailout, 1) bool recover(JSContext* cx, SnapshotIterator& iter) const; }; #undef RINSTRUCTION_HEADER_ +#undef RINSTRUCTION_HEADER_NUM_OP_ +#undef RINSTRUCTION_HEADER_NUM_OP_MAIN const RResumePoint* RInstruction::toResumePoint() const From b84ac31e1424be294dacae27b48a7646bb266749 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 10 May 2016 20:57:29 -0400 Subject: [PATCH 22/56] Bug 1271521. Add a sane way of temporarily disabling dialogs on a window. r=smaug What we have right now is not very usable, because you can only enable/disable on the scriptable top of the window, but it's not at all obvious that this is the case when using the API. --- dom/base/nsGlobalWindow.cpp | 29 +++++++++++++++++++++++++++++ dom/base/nsGlobalWindow.h | 29 ++++++++++++++++++++++++++++- layout/base/nsDocumentViewer.cpp | 8 ++------ 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index d67bd078368a..2e9ed2e9d2a2 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -14401,6 +14401,35 @@ nsGlobalWindow::CheckForDPIChange() } } +nsGlobalWindow::TemporarilyDisableDialogs::TemporarilyDisableDialogs( + nsGlobalWindow* aWindow MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) +{ + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + + MOZ_ASSERT(aWindow); + nsGlobalWindow* topWindow = aWindow->GetScriptableTopInternal(); + if (!topWindow) { + NS_ERROR("nsGlobalWindow::TemporarilyDisableDialogs used without a top " + "window?"); + return; + } + + // TODO: Warn if no top window? + topWindow = topWindow->GetCurrentInnerWindowInternal(); + if (topWindow) { + mTopWindow = topWindow; + mSavedDialogsEnabled = mTopWindow->mAreDialogsEnabled; + mTopWindow->mAreDialogsEnabled = false; + } +} + +nsGlobalWindow::TemporarilyDisableDialogs::~TemporarilyDisableDialogs() +{ + if (mTopWindow) { + mTopWindow->mAreDialogsEnabled = mSavedDialogsEnabled; + } +} + template class nsPIDOMWindow; template class nsPIDOMWindow; template class nsPIDOMWindow; diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 382f081d7cb7..fbd5c5633b76 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -42,6 +42,8 @@ #include "mozilla/dom/UnionTypes.h" #include "mozilla/ErrorResult.h" #include "nsFrameMessageManager.h" +#include "mozilla/Attributes.h" +#include "mozilla/GuardObjects.h" #include "mozilla/LinkedList.h" #include "mozilla/TimeStamp.h" #include "nsWrapperCacheInlines.h" @@ -565,12 +567,37 @@ public: bool DialogsAreBeingAbused(); // These functions are used for controlling and determining whether dialogs - // (alert, prompt, confirm) are currently allowed in this window. + // (alert, prompt, confirm) are currently allowed in this window. If you want + // to temporarily disable dialogs, please use TemporarilyDisableDialogs, not + // EnableDialogs/DisableDialogs, because correctly determining whether to + // re-enable dialogs is actually quite difficult. void EnableDialogs(); void DisableDialogs(); // Outer windows only. bool AreDialogsEnabled(); + class MOZ_RAII TemporarilyDisableDialogs + { + public: + // Takes an inner _or_ outer window. + explicit TemporarilyDisableDialogs(nsGlobalWindow* aWindow + MOZ_GUARD_OBJECT_NOTIFIER_PARAM); + ~TemporarilyDisableDialogs(); + + private: + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER + + // Always an inner window; this is the window whose dialog state we messed + // with. We just want to keep it alive, because we plan to poke at its + // members in our destructor. + RefPtr mTopWindow; + // This is not a AutoRestore because that would require careful + // member destructor ordering, which is a bit fragile. This way we can + // explicitly restore things before we drop our ref to mTopWindow. + bool mSavedDialogsEnabled; + }; + friend class TemporarilyDisableDialogs; + nsIScriptContext *GetContextInternal() { if (mOuterWindow) { diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index afd08a72fb0b..7f1a8e55ba14 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -1130,18 +1130,14 @@ nsDocumentViewer::PermitUnloadInternal(bool *aShouldPrompt, nsAutoPopupStatePusher popupStatePusher(openAbused, true); // Never permit dialogs from the beforeunload handler - nsGlobalWindow *globalWindow = - static_cast(reinterpret_cast*>(window)); + nsGlobalWindow* globalWindow = nsGlobalWindow::Cast(window); dialogsAreEnabled = globalWindow->AreDialogsEnabled(); - globalWindow->DisableDialogs(); + nsGlobalWindow::TemporarilyDisableDialogs disableDialogs(globalWindow); mInPermitUnload = true; EventDispatcher::DispatchDOMEvent(window, nullptr, event, mPresContext, nullptr); mInPermitUnload = false; - if (dialogsAreEnabled) { - globalWindow->EnableDialogs(); - } } nsCOMPtr docShell(mContainer); From 0c0359682b3eeb93f2a0e76ae7ccda1e4398fffd Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 6 May 2016 13:56:35 -0400 Subject: [PATCH 23/56] Bug 1190641 part 1. Reorder nsSandboxFlags.h to match the spec order better so it's easier to tell where they diverge. r=ckerschb --- dom/base/nsSandboxFlags.h | 51 ++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/dom/base/nsSandboxFlags.h b/dom/base/nsSandboxFlags.h index 0435db5f612b..28d3c5bfe3f3 100644 --- a/dom/base/nsSandboxFlags.h +++ b/dom/base/nsSandboxFlags.h @@ -22,11 +22,18 @@ */ const unsigned long SANDBOXED_NAVIGATION = 0x1; +/** + * This flag prevents content from creating new auxiliary browsing contexts, + * e.g. using the target attribute, the window.open() method, or the + * showModalDialog() method. + */ +const unsigned long SANDBOXED_AUXILIARY_NAVIGATION = 0x2; + /** * This flag prevents content from navigating their top-level browsing * context. */ -const unsigned long SANDBOXED_TOPLEVEL_NAVIGATION = 0x2; +const unsigned long SANDBOXED_TOPLEVEL_NAVIGATION = 0x4; /** * This flag prevents content from instantiating plugins, whether using the @@ -34,7 +41,7 @@ const unsigned long SANDBOXED_TOPLEVEL_NAVIGATION = 0x2; * navigation of a nested browsing context, unless those plugins can be * secured. */ -const unsigned long SANDBOXED_PLUGINS = 0x4; +const unsigned long SANDBOXED_PLUGINS = 0x8; /** * This flag forces content into a unique origin, thus preventing it from @@ -42,43 +49,53 @@ const unsigned long SANDBOXED_PLUGINS = 0x4; * This flag also prevents script from reading from or writing to the * document.cookie IDL attribute, and blocks access to localStorage. */ -const unsigned long SANDBOXED_ORIGIN = 0x8; +const unsigned long SANDBOXED_ORIGIN = 0x10; /** * This flag blocks form submission. */ -const unsigned long SANDBOXED_FORMS = 0x10; +const unsigned long SANDBOXED_FORMS = 0x20; + +/** + * This flag blocks the document from acquiring pointerlock. + */ +const unsigned long SANDBOXED_POINTER_LOCK = 0x40; /** * This flag blocks script execution. */ -const unsigned long SANDBOXED_SCRIPTS = 0x20; +const unsigned long SANDBOXED_SCRIPTS = 0x80; /** * This flag blocks features that trigger automatically, such as * automatically playing a video or automatically focusing a form control. */ -const unsigned long SANDBOXED_AUTOMATIC_FEATURES = 0x40; +const unsigned long SANDBOXED_AUTOMATIC_FEATURES = 0x100; /** - * This flag blocks the document from acquiring pointerlock. + * This flag prevents URL schemes that use storage areas from being able to + * access the origin's data. */ -const unsigned long SANDBOXED_POINTER_LOCK = 0x80; +// We don't have an explicit representation of this one, apparently? +// const unsigned long SANDBOXED_STORAGE_AREA_URLS = 0x200; + +/** + * This flag prevents content from using the requestFullscreen() method. + */ +// We don't implement this yet. See represent this as a sandbox flag; instead it's an explicit check for +// the "allowfullscreen" attribute on the - - + + + diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 7f1a8e55ba14..b334ebf67247 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -86,6 +86,8 @@ #include "nsIPrompt.h" #include "imgIContainer.h" // image animation mode constants +#include "nsSandboxFlags.h" + #include "mozilla/DocLoadingTimelineMarker.h" //-------------------------- @@ -1146,7 +1148,8 @@ nsDocumentViewer::PermitUnloadInternal(bool *aShouldPrompt, // NB: we nullcheck mDocument because it might now be dead as a result of // the event being dispatched. - if (!sIsBeforeUnloadDisabled && *aShouldPrompt && dialogsAreEnabled && mDocument && + if (!sIsBeforeUnloadDisabled && *aShouldPrompt && dialogsAreEnabled && + mDocument && !(mDocument->GetSandboxFlags() & SANDBOXED_MODALS) && (!sBeforeUnloadRequiresInteraction || mDocument->UserHasInteracted()) && (event->WidgetEventPtr()->DefaultPrevented() || !text.IsEmpty())) { // Ask the user if it's ok to unload the current page From 5ac1b1f8f2a4b7ca8af8618c8970fbd16dd3296e Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 6 May 2016 13:56:36 -0400 Subject: [PATCH 25/56] Bug 1190641 part 3. Add the sandbox propagates to auxiliary browsing contexts flag to iframe sandboxing. r=ckerschb --- dom/base/IframeSandboxKeywordList.h | 3 ++- dom/base/nsGkAtomList.h | 1 + dom/base/nsSandboxFlags.h | 11 ++++++-- .../windowwatcher/nsWindowWatcher.cpp | 8 +++--- testing/web-platform/meta/MANIFEST.json | 12 +++++++++ .../iframe_sandbox_popups_escaping.html | 25 +++++++++++++++++++ .../iframe_sandbox_popups_helper.html | 17 +++++++++++++ .../iframe_sandbox_popups_nonescaping.html | 15 +++++++++++ 8 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping.html create mode 100644 testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper.html create mode 100644 testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping.html diff --git a/dom/base/IframeSandboxKeywordList.h b/dom/base/IframeSandboxKeywordList.h index c7bead71891f..0b1e73e6bcad 100644 --- a/dom/base/IframeSandboxKeywordList.h +++ b/dom/base/IframeSandboxKeywordList.h @@ -23,4 +23,5 @@ SANDBOX_KEYWORD("allow-orientation-lock", alloworientationlock, SANDBOXED_ORIENTATION_LOCK) SANDBOX_KEYWORD("allow-popups", allowpopups, SANDBOXED_AUXILIARY_NAVIGATION) SANDBOX_KEYWORD("allow-modals", allowmodals, SANDBOXED_MODALS) - +SANDBOX_KEYWORD("allow-popups-to-escape-sandbox", allowpopupstoescapesandbox, + SANDBOX_PROPAGATES_TO_AUXILIARY_BROWSING_CONTEXTS) diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h index b34d1bd39059..01258eeb067f 100644 --- a/dom/base/nsGkAtomList.h +++ b/dom/base/nsGkAtomList.h @@ -82,6 +82,7 @@ GK_ATOM(allowfullscreen, "allowfullscreen") GK_ATOM(allowmodals, "allow-modals") GK_ATOM(alloworientationlock,"allow-orientation-lock") GK_ATOM(allowpointerlock,"allow-pointer-lock") +GK_ATOM(allowpopupstoescapesandbox,"allow-popups-to-escape-sandbox") GK_ATOM(allowpopups,"allow-popups") GK_ATOM(allowsameorigin,"allow-same-origin") GK_ATOM(allowscripts,"allow-scripts") diff --git a/dom/base/nsSandboxFlags.h b/dom/base/nsSandboxFlags.h index fcc99d9bb26b..ef0d2d3c9069 100644 --- a/dom/base/nsSandboxFlags.h +++ b/dom/base/nsSandboxFlags.h @@ -101,10 +101,17 @@ const unsigned long SANDBOXED_DOMAIN = 0x800; */ const unsigned long SANDBOXED_MODALS = 0x1000; +/** + * This flag prevents content from escaping the sandbox by ensuring that any + * auxiliary browsing context it creates inherits the content's active + * sandboxing flag set. + */ +const unsigned long SANDBOX_PROPAGATES_TO_AUXILIARY_BROWSING_CONTEXTS = 0x2000; + /** * This flag prevents locking screen orientation. */ -const unsigned long SANDBOXED_ORIENTATION_LOCK = 0x2000; +const unsigned long SANDBOXED_ORIENTATION_LOCK = 0x4000; -const unsigned long SANDBOX_ALL_FLAGS = 0x3FFF; +const unsigned long SANDBOX_ALL_FLAGS = 0x7FFF; #endif diff --git a/embedding/components/windowwatcher/nsWindowWatcher.cpp b/embedding/components/windowwatcher/nsWindowWatcher.cpp index fcd004f84b4b..f39220e5617c 100644 --- a/embedding/components/windowwatcher/nsWindowWatcher.cpp +++ b/embedding/components/windowwatcher/nsWindowWatcher.cpp @@ -872,9 +872,11 @@ nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy* aParent, nsCOMPtr newDocShell(do_QueryInterface(newDocShellItem)); NS_ENSURE_TRUE(newDocShell, NS_ERROR_UNEXPECTED); - // Set up sandboxing attributes if the window is new. - // The flags can only be non-zero for new windows. - if (activeDocsSandboxFlags != 0) { + // Copy sandbox flags to the new window if activeDocsSandboxFlags says to do + // so. Note that it's only nonzero if the window is new, so clobbering + // sandbox flags on the window makes sense in that case. + if (activeDocsSandboxFlags & + SANDBOX_PROPAGATES_TO_AUXILIARY_BROWSING_CONTEXTS) { newDocShell->SetSandboxFlags(activeDocsSandboxFlags); if (parentWindow) { newDocShell->SetOnePermittedSandboxedNavigator( diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 6910fc5cb441..6b4598e8127c 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -35349,6 +35349,18 @@ "url": "/html/semantics/embedded-content/the-iframe-element/iframe-load-event.html" } ], + "html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping.html": [ + { + "path": "html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping.html", + "url": "/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping.html" + } + ], + "html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping.html": [ + { + "path": "html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping.html", + "url": "/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping.html" + } + ], "html/syntax/serializing-html-fragments/serializing.html": [ { "path": "html/syntax/serializing-html-fragments/serializing.html", diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping.html new file mode 100644 index 000000000000..271f8462fda1 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping.html @@ -0,0 +1,25 @@ + + +Check that popups from a sandboxed iframe escape the sandbox if + allow-popups-to-escape-sandbox is used + + + + diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper.html new file mode 100644 index 000000000000..ee993dd0db7e --- /dev/null +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper.html @@ -0,0 +1,17 @@ + + diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping.html new file mode 100644 index 000000000000..546f9d53d330 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping.html @@ -0,0 +1,15 @@ + + +Check that popups from a sandboxed iframe do not escape the sandbox + + + + From 72f9bd44e02eed333c8872579641ccbac87070a0 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 10 May 2016 20:57:29 -0400 Subject: [PATCH 26/56] Bug 1270349 followup to address a review comment. r=peterv --- dom/base/nsMimeTypeArray.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dom/base/nsMimeTypeArray.cpp b/dom/base/nsMimeTypeArray.cpp index 8434dcd99909..d99b37df7ac9 100644 --- a/dom/base/nsMimeTypeArray.cpp +++ b/dom/base/nsMimeTypeArray.cpp @@ -90,7 +90,7 @@ nsMimeTypeArray::IndexedGetter(uint32_t aIndex, bool &aFound) } static nsMimeType* -FindMimeType(const nsTArray >& aMimeTypes, +FindMimeType(const nsTArray>& aMimeTypes, const nsAString& aType) { for (uint32_t i = 0; i < aMimeTypes.Length(); ++i) { @@ -131,7 +131,7 @@ nsMimeTypeArray::Length() } void -nsMimeTypeArray::GetSupportedNames(nsTArray< nsString >& aRetval) +nsMimeTypeArray::GetSupportedNames(nsTArray& aRetval) { EnsurePluginMimeTypes(); From 20a2c90769b8d742b5bcfe6b117e1fe81bf2919c Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 10 May 2016 20:57:29 -0400 Subject: [PATCH 27/56] Bug 1268845. Make sure to set up an XPCWrappedNativeScope for SimpleGlobalObject globals on the main thread. r=bholley,ttaubert,ejpbruel --- dom/bindings/SimpleGlobalObject.cpp | 22 +++++++------ .../test/test_WebCrypto_Wrap_Unwrap.html | 32 +++++++++++++++++++ dom/workers/WorkerPrivate.cpp | 21 ++++++++++-- js/xpconnect/src/nsXPConnect.cpp | 23 +++++++------ 4 files changed, 76 insertions(+), 22 deletions(-) diff --git a/dom/bindings/SimpleGlobalObject.cpp b/dom/bindings/SimpleGlobalObject.cpp index 95399f406fb8..0782bc2f7f85 100644 --- a/dom/bindings/SimpleGlobalObject.cpp +++ b/dom/bindings/SimpleGlobalObject.cpp @@ -96,15 +96,19 @@ SimpleGlobalObject::Create(GlobalType globalType, JS::Handle proto) JS::CompartmentOptions options; options.creationOptions().setInvisibleToDebugger(true); - nsCOMPtr principal; - if (NS_IsMainThread()) { - principal = nsNullPrincipal::Create(); - } + JS::Rooted global(cx); - JS::Rooted global(cx, - JS_NewGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass), - nsJSPrincipals::get(principal), - JS::DontFireOnNewGlobalHook, options)); + if (NS_IsMainThread()) { + nsCOMPtr principal = nsNullPrincipal::Create(); + options.creationOptions().setTrace(xpc::TraceXPCGlobal); + global = xpc::CreateGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass), + nsJSPrincipals::get(principal), + options); + } else { + global = JS_NewGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass), + nullptr, + JS::DontFireOnNewGlobalHook, options); + } if (!global) { JS_ClearPendingException(cx); @@ -130,7 +134,7 @@ SimpleGlobalObject::Create(GlobalType globalType, JS::Handle proto) return nullptr; } - if (!JS_SetPrototype(cx, global, protoObj)) { + if (!JS_SplicePrototype(cx, global, protoObj)) { JS_ClearPendingException(cx); return nullptr; } diff --git a/dom/crypto/test/test_WebCrypto_Wrap_Unwrap.html b/dom/crypto/test/test_WebCrypto_Wrap_Unwrap.html index 30ce36710d3d..c2c7e57e688b 100644 --- a/dom/crypto/test/test_WebCrypto_Wrap_Unwrap.html +++ b/dom/crypto/test/test_WebCrypto_Wrap_Unwrap.html @@ -307,6 +307,38 @@ TestArray.addTest( ); } ); + +// ----------------------------------------------------------------------------- +TestArray.addTest( + "JWK unwrap attempt on bogus data should error out", + function () { + // Largely cribbed from the "JWK wrap/unwrap round-trip, with AES-GCM" test + var that = this; + var wrapAlg = { name: "AES-GCM", iv: tv.aes_gcm_enc.iv }; + var wrapKey; + + function doBogusWrap() { + var abv = new TextEncoder("utf-8").encode("I am so not JSON"); + return crypto.subtle.encrypt(wrapAlg, wrapKey, abv); + } + function doUnwrap(wrappedKey) { + return crypto.subtle.unwrapKey("jwk", wrappedKey, wrapKey, wrapAlg, + {name: "HMAC", hash: "SHA-384"}, + true, ['sign', 'verify']); + } + + crypto.subtle.importKey("jwk", tv.aes_gcm_enc.key_jwk, + "AES-GCM", false, ['encrypt','unwrapKey']) + .then(function(x) { wrapKey = x; }) + .then(doBogusWrap, error(that)) + .then(doUnwrap, error(that)) + .then( + error(that), + complete(that) + ); + } +); + /*]]>*/ diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 2fe5de0611f2..fd411897a0fd 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -59,6 +59,7 @@ #include "mozilla/dom/PMessagePort.h" #include "mozilla/dom/Promise.h" #include "mozilla/dom/PromiseDebugging.h" +#include "mozilla/dom/SimpleGlobalObject.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/StructuredCloneHolder.h" #include "mozilla/dom/TabChild.h" @@ -1058,6 +1059,11 @@ public: // Now fire an event at the global object, but don't do that if the error // code is too much recursion and this is the same script threw the error. + // XXXbz the interaction of this with worker errors seems kinda broken. + // An overrecursion in the debugger or debugger sandbox will get turned + // into an error event on our parent worker! + // https://bugzilla.mozilla.org/show_bug.cgi?id=1271441 tracks making this + // better. if (aFireAtScope && (aTarget || aErrorNumber != JSMSG_OVER_RECURSED)) { JS::Rooted global(aCx, JS::CurrentGlobalOrNull(aCx)); NS_ASSERTION(global, "This should never be null!"); @@ -1074,10 +1080,19 @@ public: UNWRAP_OBJECT(WorkerDebuggerGlobalScope, global, globalScope); MOZ_ASSERT_IF(globalScope, globalScope->GetWrapperPreserveColor() == global); - MOZ_ASSERT_IF(!globalScope, IsDebuggerSandbox(global)); + if (globalScope || IsDebuggerSandbox(global)) { + aWorkerPrivate->ReportErrorToDebugger(aFilename, aLineNumber, + aMessage); + return; + } - aWorkerPrivate->ReportErrorToDebugger(aFilename, aLineNumber, - aMessage); + MOZ_ASSERT(SimpleGlobalObject::SimpleGlobalType(global) == + SimpleGlobalObject::GlobalType::BindingDetail); + // XXXbz We should really log this to console, but unwinding out of + // this stuff without ending up firing any events is ... hard. Just + // return for now. + // https://bugzilla.mozilla.org/show_bug.cgi?id=1271441 tracks + // making this better. return; } diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index 7f899fa3baa2..d33d8af7454a 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -402,19 +402,22 @@ CreateGlobalObject(JSContext* cx, const JSClass* clasp, nsIPrincipal* principal, // of |global|. (void) new XPCWrappedNativeScope(cx, global); + if (clasp->flags & JSCLASS_DOM_GLOBAL) { #ifdef DEBUG - // Verify that the right trace hook is called. Note that this doesn't - // work right for wrapped globals, since the tracing situation there is - // more complicated. Manual inspection shows that they do the right thing. - if (!((const js::Class*)clasp)->isWrappedNative()) - { - VerifyTraceProtoAndIfaceCacheCalledTracer trc(JS_GetRuntime(cx)); - TraceChildren(&trc, GCCellPtr(global.get())); - MOZ_ASSERT(trc.ok, "Trace hook on global needs to call TraceXPCGlobal for XPConnect compartments."); - } + // Verify that the right trace hook is called. Note that this doesn't + // work right for wrapped globals, since the tracing situation there is + // more complicated. Manual inspection shows that they do the right + // thing. Also note that we only check this for JSCLASS_DOM_GLOBAL + // classes because xpc::TraceXPCGlobal won't call + // TraceProtoAndIfaceCache unless that flag is set. + if (!((const js::Class*)clasp)->isWrappedNative()) + { + VerifyTraceProtoAndIfaceCacheCalledTracer trc(JS_GetRuntime(cx)); + TraceChildren(&trc, GCCellPtr(global.get())); + MOZ_ASSERT(trc.ok, "Trace hook on global needs to call TraceXPCGlobal for XPConnect compartments."); + } #endif - if (clasp->flags & JSCLASS_DOM_GLOBAL) { const char* className = clasp->name; AllocateProtoAndIfaceCache(global, (strcmp(className, "Window") == 0 || From 43fdb89cf1ac0fe2a8ea10088483ac0a55563b2e Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 10 May 2016 22:21:40 -0400 Subject: [PATCH 28/56] No bug - Add more chunks to Taskcluster reftest and web-platform-test jobs. --- testing/taskcluster/tasks/tests/fx_linux64_reftest_e10s.yml | 2 +- .../tasks/tests/fx_linux64_reftest_not_accelerated.yml | 2 +- .../tasks/tests/fx_linux64_reftest_not_accelerated_e10s.yml | 2 +- .../taskcluster/tasks/tests/fx_linux64_web_platform_tests.yml | 2 +- .../tasks/tests/fx_linux64_web_platform_tests_e10s.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/taskcluster/tasks/tests/fx_linux64_reftest_e10s.yml b/testing/taskcluster/tasks/tests/fx_linux64_reftest_e10s.yml index 3a67b946f6dd..7e26d2bdfafe 100644 --- a/testing/taskcluster/tasks/tests/fx_linux64_reftest_e10s.yml +++ b/testing/taskcluster/tasks/tests/fx_linux64_reftest_e10s.yml @@ -22,7 +22,7 @@ task: description: Reftest e10s run {{chunk}} extra: chunks: - total: 5 + total: 8 suite: name: reftest flavor: reftest diff --git a/testing/taskcluster/tasks/tests/fx_linux64_reftest_not_accelerated.yml b/testing/taskcluster/tasks/tests/fx_linux64_reftest_not_accelerated.yml index 920f337a531d..e457652fa805 100644 --- a/testing/taskcluster/tasks/tests/fx_linux64_reftest_not_accelerated.yml +++ b/testing/taskcluster/tasks/tests/fx_linux64_reftest_not_accelerated.yml @@ -21,7 +21,7 @@ task: description: Reftest not accelerated run {{chunk}} extra: chunks: - total: 2 + total: 8 suite: name: reftest flavor: reftest-no-accel diff --git a/testing/taskcluster/tasks/tests/fx_linux64_reftest_not_accelerated_e10s.yml b/testing/taskcluster/tasks/tests/fx_linux64_reftest_not_accelerated_e10s.yml index 497294602f61..1cfb931e6a4b 100644 --- a/testing/taskcluster/tasks/tests/fx_linux64_reftest_not_accelerated_e10s.yml +++ b/testing/taskcluster/tasks/tests/fx_linux64_reftest_not_accelerated_e10s.yml @@ -22,7 +22,7 @@ task: description: Reftest not accelerated e10s run {{chunk}} extra: chunks: - total: 2 + total: 8 suite: name: reftest flavor: reftest-no-accel diff --git a/testing/taskcluster/tasks/tests/fx_linux64_web_platform_tests.yml b/testing/taskcluster/tasks/tests/fx_linux64_web_platform_tests.yml index 818337549b0e..03b92240a0d2 100644 --- a/testing/taskcluster/tasks/tests/fx_linux64_web_platform_tests.yml +++ b/testing/taskcluster/tasks/tests/fx_linux64_web_platform_tests.yml @@ -22,7 +22,7 @@ task: description: Web platform tests run {{chunk}} extra: chunks: - total: 8 + total: 12 suite: name: web-platform-tests flavor: web-platform-tests diff --git a/testing/taskcluster/tasks/tests/fx_linux64_web_platform_tests_e10s.yml b/testing/taskcluster/tasks/tests/fx_linux64_web_platform_tests_e10s.yml index 3e04a5847522..a69615a92c38 100644 --- a/testing/taskcluster/tasks/tests/fx_linux64_web_platform_tests_e10s.yml +++ b/testing/taskcluster/tasks/tests/fx_linux64_web_platform_tests_e10s.yml @@ -23,7 +23,7 @@ task: description: Web platform e10s tests run {{chunk}} extra: chunks: - total: 8 + total: 12 treeherder: groupName: Desktop web-platform-tests groupSymbol: tc-W-e10s From e6b875b2dea34a967fa9bc183a9860e56879b81e Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 10 May 2016 22:23:29 -0400 Subject: [PATCH 29/56] Bug 1252405 - Add fuzz to bg-fixed-child-mask.html for Windows e10s D2D. r=sotaro --- layout/reftests/async-scrolling/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/async-scrolling/reftest.list b/layout/reftests/async-scrolling/reftest.list index 1dce7c9b2c8b..8ef04b05f59c 100644 --- a/layout/reftests/async-scrolling/reftest.list +++ b/layout/reftests/async-scrolling/reftest.list @@ -5,7 +5,7 @@ skip-if(!asyncPan) == bg-fixed-cover-3.html bg-fixed-cover-3-ref.html skip-if(!asyncPan) == bg-fixed-child.html bg-fixed-child-ref.html skip-if(!asyncPan) == bg-fixed-child-clip-1.html bg-fixed-child-clip-ref.html skip-if(!asyncPan) == bg-fixed-child-clip-2.html bg-fixed-child-clip-ref.html -fuzzy(1,246) fuzzy-if(skiaContent,2,160) skip-if(!asyncPan) == bg-fixed-child-mask.html bg-fixed-child-mask-ref.html +fuzzy(1,246) fuzzy-if(skiaContent,2,160) fuzzy-if(browserIsRemote&&d2d,53,185) skip-if(!asyncPan) == bg-fixed-child-mask.html bg-fixed-child-mask-ref.html skip-if(!asyncPan) == bg-fixed-in-opacity.html bg-fixed-in-opacity-ref.html skip-if(!asyncPan) == bg-fixed-child-no-culling.html bg-fixed-child-no-culling-ref.html fuzzy-if(B2G,2,5366) fuzzy-if(Android,2,4000) fuzzy-if(browserIsRemote&&cocoaWidget,2,179524) fuzzy-if(browserIsRemote&&winWidget,1,74590) skip-if(!asyncPan) == bg-fixed-transformed-image.html bg-fixed-transformed-image-ref.html From 9978fb20b227e5f431d39ebf62caa927dc0ecc17 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 10 May 2016 22:35:29 -0400 Subject: [PATCH 30/56] Backed out changeset ab611defdc9b (bug 1271407) for slowing down debug mochitests and causing frequent oranges as a result. --- js/src/jsscript.cpp | 12 ++++-------- js/src/jsscript.h | 22 ++++++++++++++++++---- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 3e89b6da6603..ec62710c357a 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1884,8 +1884,8 @@ ScriptSource::sourceText(JSContext* cx) return mozilla::Nothing(); } - if (!DecompressString((const unsigned char*) c.raw.chars(), - c.raw.length(), + if (!DecompressString((const unsigned char*) ss.compressedData(), + ss.compressedBytes(), reinterpret_cast(decompressed.get()), lengthWithNull * sizeof(char16_t))) { @@ -2051,8 +2051,6 @@ ScriptSource::setSourceCopy(ExclusiveContext* cx, SourceBufferHolder& srcBuf, SourceCompressionTask::ResultType SourceCompressionTask::work() { - MOZ_ASSERT(ss->data.is()); - // Try to keep the maximum memory usage down by only allocating half the // size of the string, first. size_t inputBytes = ss->length() * sizeof(char16_t); @@ -2061,9 +2059,7 @@ SourceCompressionTask::work() if (!compressed) return OOM; - const char16_t* chars = ss->data.as().string.chars(); - Compressor comp(reinterpret_cast(chars), - inputBytes); + Compressor comp(reinterpret_cast(ss->uncompressedChars()), inputBytes); if (!comp.init()) return OOM; @@ -2131,7 +2127,7 @@ ScriptSource::performXDR(XDRState* xdr) } ReturnType match(Compressed& c) { - return c.raw.length(); + return c.nbytes(); } ReturnType match(Missing&) { diff --git a/js/src/jsscript.h b/js/src/jsscript.h index cf7caef48e73..76bdc5ba4109 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -620,12 +620,14 @@ class ScriptSource struct Compressed { SharedImmutableString raw; - size_t uncompressedLength; + size_t length; - Compressed(SharedImmutableString&& raw, size_t uncompressedLength) + Compressed(SharedImmutableString&& raw, size_t length) : raw(mozilla::Move(raw)) - , uncompressedLength(uncompressedLength) + , length(length) { } + + size_t nbytes() const { return raw.length(); } }; using SourceType = mozilla::Variant; @@ -722,7 +724,7 @@ class ScriptSource } ReturnType match(const Compressed& c) { - return c.uncompressedLength; + return c.length; } ReturnType match(const Missing& m) { @@ -749,6 +751,18 @@ class ScriptSource void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::ScriptSourceInfo* info) const; + const char16_t* uncompressedChars() const { + return data.as().string.chars(); + } + + const void* compressedData() const { + return static_cast(data.as().raw.chars()); + } + + size_t compressedBytes() const { + return data.as().nbytes(); + } + MOZ_MUST_USE bool setSource(ExclusiveContext* cx, mozilla::UniquePtr&& source, size_t length); From c3a556622b3f81108bb082fb4695e9ff3d238e6c Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 10 May 2016 22:35:57 -0400 Subject: [PATCH 31/56] Backed out changeset e4590851081d (bug 1269451) for slowing down debug mochitests and causing frequent oranges as a result. CLOSED TREE --- js/src/jsfun.cpp | 7 +- js/src/jsscript.cpp | 172 +++++++++++++++++++++++++++++++------------- js/src/jsscript.h | 51 ++++++++----- 3 files changed, 162 insertions(+), 68 deletions(-) diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index edf5d4650c78..f56ef64c7c43 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -1437,11 +1437,12 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext* cx, HandleFuncti MOZ_ASSERT(lazy->scriptSource()->hasSourceData()); // Parse and compile the script from source. - auto text = lazy->scriptSource()->sourceText(cx); - if (!text) + UncompressedSourceCache::AutoHoldEntry holder; + const char16_t* chars = lazy->scriptSource()->chars(cx, holder); + if (!chars) return false; - const char16_t* lazyStart = text->chars() + lazy->begin(); + const char16_t* lazyStart = chars + lazy->begin(); size_t lazyLength = lazy->end() - lazy->begin(); if (!frontend::CompileLazyFunction(cx, lazy, lazyStart, lazyLength)) { diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index ec62710c357a..b274e9f8b4b2 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1812,19 +1812,73 @@ JSScript::sourceData(JSContext* cx) return scriptSource()->substring(cx, sourceStart(), sourceEnd()); } -mozilla::Maybe -UncompressedSourceCache::lookup(ScriptSource* ss) +UncompressedSourceCache::AutoHoldEntry::AutoHoldEntry() + : cache_(nullptr), source_(nullptr) { +} + +void +UncompressedSourceCache::AutoHoldEntry::holdEntry(UncompressedSourceCache* cache, ScriptSource* source) +{ + // Initialise the holder for a specific cache and script source. This will + // hold on to the cached source chars in the event that the cache is purged. + MOZ_ASSERT(!cache_ && !source_ && !charsToFree_); + cache_ = cache; + source_ = source; +} + +void +UncompressedSourceCache::AutoHoldEntry::deferDelete(UniqueTwoByteChars chars) +{ + // Take ownership of source chars now the cache is being purged. Remove our + // reference to the ScriptSource which might soon be destroyed. + MOZ_ASSERT(cache_ && source_ && !charsToFree_); + cache_ = nullptr; + source_ = nullptr; + charsToFree_ = Move(chars); +} + +UncompressedSourceCache::AutoHoldEntry::~AutoHoldEntry() +{ + if (cache_) { + MOZ_ASSERT(source_); + cache_->releaseEntry(*this); + } +} + +void +UncompressedSourceCache::holdEntry(AutoHoldEntry& holder, ScriptSource* ss) +{ + MOZ_ASSERT(!holder_); + holder.holdEntry(this, ss); + holder_ = &holder; +} + +void +UncompressedSourceCache::releaseEntry(AutoHoldEntry& holder) +{ + MOZ_ASSERT(holder_ == &holder); + holder_ = nullptr; +} + +const char16_t* +UncompressedSourceCache::lookup(ScriptSource* ss, AutoHoldEntry& holder) +{ + MOZ_ASSERT(!holder_); if (!map_) - return mozilla::Nothing(); - if (Map::Ptr p = map_->lookup(ss)) - return mozilla::Some(p->value().clone()); - return mozilla::Nothing(); + return nullptr; + if (Map::Ptr p = map_->lookup(ss)) { + holdEntry(holder, ss); + return p->value().get(); + } + return nullptr; } bool -UncompressedSourceCache::put(ScriptSource* ss, SharedImmutableTwoByteString&& str) +UncompressedSourceCache::put(ScriptSource* ss, UniqueTwoByteChars str, AutoHoldEntry& holder) { + MOZ_ASSERT(!holder_); + if (!map_) { UniquePtr map = MakeUnique(); if (!map || !map->init()) @@ -1833,7 +1887,11 @@ UncompressedSourceCache::put(ScriptSource* ss, SharedImmutableTwoByteString&& st map_ = Move(map); } - return map_->put(ss, Move(str)); + if (!map_->put(ss, Move(str))) + return false; + + holdEntry(holder, ss); + return true; } void @@ -1842,6 +1900,13 @@ UncompressedSourceCache::purge() if (!map_) return; + for (Map::Range r = map_->all(); !r.empty(); r.popFront()) { + if (holder_ && r.front().key() == holder_->source()) { + holder_->deferDelete(Move(r.front().value())); + holder_ = nullptr; + } + } + map_.reset(); } @@ -1849,39 +1914,45 @@ size_t UncompressedSourceCache::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) { size_t n = 0; - if (map_ && !map_->empty()) + if (map_ && !map_->empty()) { n += map_->sizeOfIncludingThis(mallocSizeOf); + for (Map::Range r = map_->all(); !r.empty(); r.popFront()) + n += mallocSizeOf(r.front().value().get()); + } return n; } -mozilla::Maybe -ScriptSource::sourceText(JSContext* cx) +const char16_t* +ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holder) { - struct SourceTextMatcher + struct CharsMatcher { - using ReturnType = mozilla::Maybe; + using ReturnType = const char16_t*; JSContext* cx; ScriptSource& ss; + UncompressedSourceCache::AutoHoldEntry& holder; - explicit SourceTextMatcher(JSContext* cx, ScriptSource& ss) + explicit CharsMatcher(JSContext* cx, ScriptSource& ss, + UncompressedSourceCache::AutoHoldEntry& holder) : cx(cx) , ss(ss) + , holder(holder) { } ReturnType match(Uncompressed& u) { - return mozilla::Some(u.string.clone()); + return u.string.chars(); } ReturnType match(Compressed& c) { - if (auto decompressed = cx->runtime()->uncompressedSourceCache.lookup(&ss)) - return mozilla::Some(mozilla::Move(*decompressed)); + if (const char16_t* decompressed = cx->runtime()->uncompressedSourceCache.lookup(&ss, holder)) + return decompressed; const size_t lengthWithNull = ss.length() + 1; UniqueTwoByteChars decompressed(js_pod_malloc(lengthWithNull)); if (!decompressed) { - ReportOutOfMemory(cx); - return mozilla::Nothing(); + JS_ReportOutOfMemory(cx); + return nullptr; } if (!DecompressString((const unsigned char*) ss.compressedData(), @@ -1889,44 +1960,43 @@ ScriptSource::sourceText(JSContext* cx) reinterpret_cast(decompressed.get()), lengthWithNull * sizeof(char16_t))) { - ReportOutOfMemory(cx); - return mozilla::Nothing(); + JS_ReportOutOfMemory(cx); + return nullptr; } decompressed[ss.length()] = 0; - auto& strings = cx->runtime()->sharedImmutableStrings(); - auto deduped = strings.getOrCreate(mozilla::Move(decompressed), ss.length()); - if (!deduped) { - ReportOutOfMemory(cx); - return mozilla::Nothing(); - } - // Decompressing a huge script is expensive. With lazy parsing and // relazification, this can happen repeatedly, so conservatively go // back to storing the data uncompressed to avoid wasting too much // time yo-yoing back and forth between compressed and uncompressed. const size_t HUGE_SCRIPT = 5 * 1024 * 1024; if (lengthWithNull > HUGE_SCRIPT) { - ss.data = SourceType(Uncompressed(deduped->clone())); - return mozilla::Some(mozilla::Move(*deduped)); + auto& strings = cx->runtime()->sharedImmutableStrings(); + auto str = strings.getOrCreate(mozilla::Move(decompressed), ss.length()); + if (!str) { + JS_ReportOutOfMemory(cx); + return nullptr; + } + ss.data = SourceType(Uncompressed(mozilla::Move(*str))); + return ss.uncompressedChars(); } - if (!cx->runtime()->uncompressedSourceCache.put(&ss, deduped->clone())) { - ReportOutOfMemory(cx); - return mozilla::Nothing(); + ReturnType ret = decompressed.get(); + if (!cx->runtime()->uncompressedSourceCache.put(&ss, Move(decompressed), holder)) { + JS_ReportOutOfMemory(cx); + return nullptr; } - - return mozilla::Some(mozilla::Move(*deduped)); + return ret; } ReturnType match(Missing&) { - MOZ_CRASH("ScriptSource::sourceText() on ScriptSource with SourceType = Missing"); - return mozilla::Nothing(); + MOZ_CRASH("ScriptSource::chars() on ScriptSource with SourceType = Missing"); + return nullptr; } }; - SourceTextMatcher cm(cx, *this); + CharsMatcher cm(cx, *this, holder); return data.match(cm); } @@ -1934,20 +2004,22 @@ JSFlatString* ScriptSource::substring(JSContext* cx, uint32_t start, uint32_t stop) { MOZ_ASSERT(start <= stop); - auto text = sourceText(cx); - if (!text) + UncompressedSourceCache::AutoHoldEntry holder; + const char16_t* chars = this->chars(cx, holder); + if (!chars) return nullptr; - return NewStringCopyN(cx, text->chars() + start, stop - start); + return NewStringCopyN(cx, chars + start, stop - start); } JSFlatString* ScriptSource::substringDontDeflate(JSContext* cx, uint32_t start, uint32_t stop) { MOZ_ASSERT(start <= stop); - auto text = sourceText(cx); - if (!text) + UncompressedSourceCache::AutoHoldEntry holder; + const char16_t* chars = this->chars(cx, holder); + if (!chars) return nullptr; - return NewStringCopyNDontDeflate(cx, text->chars() + start, stop - start); + return NewStringCopyNDontDeflate(cx, chars + start, stop - start); } MOZ_MUST_USE bool @@ -4396,17 +4468,19 @@ LazyScriptHashPolicy::match(JSScript* script, const Lookup& lookup) return false; } - auto scriptText = script->scriptSource()->sourceText(cx); - if (!scriptText) + UncompressedSourceCache::AutoHoldEntry holder; + + const char16_t* scriptChars = script->scriptSource()->chars(cx, holder); + if (!scriptChars) return false; - auto lazyText = lazy->scriptSource()->sourceText(cx); - if (!lazyText) + const char16_t* lazyChars = lazy->scriptSource()->chars(cx, holder); + if (!lazyChars) return false; size_t begin = script->sourceStart(); size_t length = script->sourceEnd() - begin; - return !memcmp(scriptText->chars() + begin, lazyText->chars() + begin, length); + return !memcmp(scriptChars + begin, lazyChars + begin, length); } void diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 76bdc5ba4109..e5dd7a82846e 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -10,8 +10,6 @@ #define jsscript_h #include "mozilla/Atomics.h" -#include "mozilla/Attributes.h" -#include "mozilla/Maybe.h" #include "mozilla/MemoryReporting.h" #include "mozilla/PodOperations.h" #include "mozilla/Variant.h" @@ -578,20 +576,45 @@ class ScriptSource; class UncompressedSourceCache { - using Map = HashMap, - SystemAllocPolicy>; - - UniquePtr map_; + typedef HashMap, + SystemAllocPolicy> Map; public: - UncompressedSourceCache() { } + // Hold an entry in the source data cache and prevent it from being purged on GC. + class AutoHoldEntry + { + UncompressedSourceCache* cache_; + ScriptSource* source_; + UniqueTwoByteChars charsToFree_; + public: + explicit AutoHoldEntry(); + ~AutoHoldEntry(); + private: + void holdEntry(UncompressedSourceCache* cache, ScriptSource* source); + void deferDelete(UniqueTwoByteChars chars); + ScriptSource* source() const { return source_; } + friend class UncompressedSourceCache; + }; + + private: + UniquePtr map_; + AutoHoldEntry* holder_; + + public: + UncompressedSourceCache() : holder_(nullptr) {} + + const char16_t* lookup(ScriptSource* ss, AutoHoldEntry& asp); + bool put(ScriptSource* ss, UniqueTwoByteChars chars, AutoHoldEntry& asp); - MOZ_MUST_USE mozilla::Maybe lookup(ScriptSource* ss); - bool put(ScriptSource* ss, SharedImmutableTwoByteString&& chars); void purge(); + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf); + + private: + void holdEntry(AutoHoldEntry& holder, ScriptSource* ss); + void releaseEntry(AutoHoldEntry& holder); }; class ScriptSource @@ -741,11 +764,7 @@ class ScriptSource MOZ_ASSERT(hasSourceData()); return argumentsNotIncluded_; } - - // Get a handle on the underlying source text. Returns mozilla::Nothing on - // OOM failure. - MOZ_MUST_USE mozilla::Maybe sourceText(JSContext* cx); - + const char16_t* chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& asp); JSFlatString* substring(JSContext* cx, uint32_t start, uint32_t stop); JSFlatString* substringDontDeflate(JSContext* cx, uint32_t start, uint32_t stop); void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, From 5c2d03855b4266025f968364e4725b9d82a9a395 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Tue, 10 May 2016 20:42:13 -0700 Subject: [PATCH 32/56] Back out 24d2a5003aa4 (bug 1271784) for Win7 mochitest-gl unexpected passes on opt and timeouts on debug CLOSED TREE --- gfx/angle/moz.build | 1 - gfx/angle/src/commit.h | 4 ++-- gfx/angle/src/libANGLE/moz.build | 1 - gfx/angle/src/libEGL/moz.build | 1 - gfx/angle/src/libGLESv2/moz.build | 1 - 5 files changed, 2 insertions(+), 6 deletions(-) diff --git a/gfx/angle/moz.build b/gfx/angle/moz.build index 663627b1a1fd..49f681ffc5c4 100644 --- a/gfx/angle/moz.build +++ b/gfx/angle/moz.build @@ -138,7 +138,6 @@ if not CONFIG['MOZ_DEBUG']: DEFINES['_SECURE_SCL'] = 0 DEFINES['ANGLE_ENABLE_D3D9'] = True -DEFINES['ANGLE_SKIP_DXGI_1_2_CHECK'] = True if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']: DEFINES['ANGLE_ENABLE_D3D11'] = True diff --git a/gfx/angle/src/commit.h b/gfx/angle/src/commit.h index 0a372d999807..12ca80c7c5f5 100644 --- a/gfx/angle/src/commit.h +++ b/gfx/angle/src/commit.h @@ -1,3 +1,3 @@ -#define ANGLE_COMMIT_HASH "0ed5ff9d075e" +#define ANGLE_COMMIT_HASH "f1101625dbbe" #define ANGLE_COMMIT_HASH_SIZE 12 -#define ANGLE_COMMIT_DATE "2016-04-29 17:26:19 -0400" +#define ANGLE_COMMIT_DATE "2016-02-24 21:04:03 -0500" diff --git a/gfx/angle/src/libANGLE/moz.build b/gfx/angle/src/libANGLE/moz.build index 153a8a9b862e..6d8275c32436 100644 --- a/gfx/angle/src/libANGLE/moz.build +++ b/gfx/angle/src/libANGLE/moz.build @@ -292,7 +292,6 @@ if not CONFIG['MOZ_DEBUG']: DEFINES['_SECURE_SCL'] = 0 DEFINES['ANGLE_ENABLE_D3D9'] = True -DEFINES['ANGLE_SKIP_DXGI_1_2_CHECK'] = True if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']: DEFINES['ANGLE_ENABLE_D3D11'] = True diff --git a/gfx/angle/src/libEGL/moz.build b/gfx/angle/src/libEGL/moz.build index 8e99d44ff713..4000b964e975 100644 --- a/gfx/angle/src/libEGL/moz.build +++ b/gfx/angle/src/libEGL/moz.build @@ -42,7 +42,6 @@ if not CONFIG['MOZ_DEBUG']: DEFINES['_SECURE_SCL'] = 0 DEFINES['ANGLE_ENABLE_D3D9'] = True -DEFINES['ANGLE_SKIP_DXGI_1_2_CHECK'] = True if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']: DEFINES['ANGLE_ENABLE_D3D11'] = True diff --git a/gfx/angle/src/libGLESv2/moz.build b/gfx/angle/src/libGLESv2/moz.build index a004425d873a..404408d45536 100644 --- a/gfx/angle/src/libGLESv2/moz.build +++ b/gfx/angle/src/libGLESv2/moz.build @@ -48,7 +48,6 @@ if not CONFIG['MOZ_DEBUG']: DEFINES['_SECURE_SCL'] = 0 DEFINES['ANGLE_ENABLE_D3D9'] = True -DEFINES['ANGLE_SKIP_DXGI_1_2_CHECK'] = True if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']: DEFINES['ANGLE_ENABLE_D3D11'] = True From e68880b733098d29c564b15d632d248d355351c3 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Tue, 10 May 2016 22:57:53 -0500 Subject: [PATCH 33/56] Bug 1263472. Limit the height of svg embed in image/test/mochitest/test_svg_animatedGIF.html. r=xidorn The extra height of the test element (the embed) versus the reference element (a div with height 40px) can cause the iframe the test is run in to overflow, thus causing a scrollbar in the test but not the reference. But we are only interested in testing the frame of the contained animated gif. --- image/test/mochitest/test_svg_animatedGIF.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/image/test/mochitest/test_svg_animatedGIF.html b/image/test/mochitest/test_svg_animatedGIF.html index cc4383397155..aa9445e00369 100644 --- a/image/test/mochitest/test_svg_animatedGIF.html +++ b/image/test/mochitest/test_svg_animatedGIF.html @@ -28,7 +28,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=666446 the VectorImage class for SVG, whereas in this test, we are testing RasterImage. --> - +

From 45e8820b950b96d4231c275d6539390ef6832fc2 Mon Sep 17 00:00:00 2001
From: Timothy Nikkel 
Date: Tue, 10 May 2016 22:58:26 -0500
Subject: [PATCH 34/56] Bug 1261752. Part 1. r=mats

---
 view/nsViewManager.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/view/nsViewManager.cpp b/view/nsViewManager.cpp
index 70ba8d2f578a..f2e8a0de27a9 100644
--- a/view/nsViewManager.cpp
+++ b/view/nsViewManager.cpp
@@ -446,7 +446,7 @@ nsViewManager::ProcessPendingUpdatesPaint(nsIWidget* aWidget)
   if (aWidget->NeedsPaint()) {
     // If an ancestor widget was hidden and then shown, we could
     // have a delayed resize to handle.
-    for (nsViewManager *vm = this; vm;
+    for (RefPtr vm = this; vm;
          vm = vm->mRootView->GetParent()
            ? vm->mRootView->GetParent()->GetViewManager()
            : nullptr) {

From bca5591f1e8ba216aa410f1110ff7ca8d542eaf2 Mon Sep 17 00:00:00 2001
From: Timothy Nikkel 
Date: Tue, 10 May 2016 22:58:47 -0500
Subject: [PATCH 35/56] Bug 1261752. Part 2. r=mats

---
 view/nsViewManager.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/view/nsViewManager.cpp b/view/nsViewManager.cpp
index f2e8a0de27a9..4b2204578c3c 100644
--- a/view/nsViewManager.cpp
+++ b/view/nsViewManager.cpp
@@ -400,7 +400,7 @@ nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
     }
   }
   if (rootShell->GetViewManager() != this) {
-    return; // 'this' might have been destroyed
+    return; // presentation might have been torn down
   }
   if (aFlushDirtyRegion) {
     profiler_tracing("Paint", "DisplayList", TRACING_INTERVAL_START);
@@ -1110,6 +1110,7 @@ nsViewManager::ProcessPendingUpdates()
   if (mPresShell) {
     mPresShell->GetPresContext()->RefreshDriver()->RevokeViewManagerFlush();
 
+    RefPtr strongThis(this);
     CallWillPaintOnObservers();
 
     ProcessPendingUpdatesForView(mRootView, true);
@@ -1126,6 +1127,7 @@ nsViewManager::UpdateWidgetGeometry()
 
   if (mHasPendingWidgetGeometryChanges) {
     mHasPendingWidgetGeometryChanges = false;
+    RefPtr strongThis(this);
     ProcessPendingUpdatesForView(mRootView, false);
   }
 }

From bf94e2fc4e0f06f8acef155afd6d9b53c2ddf953 Mon Sep 17 00:00:00 2001
From: Timothy Nikkel 
Date: Tue, 10 May 2016 22:58:47 -0500
Subject: [PATCH 36/56] Bug 1261752. Part 3. r=mats

---
 layout/forms/nsComboboxControlFrame.cpp |  6 ++++-
 view/nsViewManager.cpp                  |  9 +++----
 widget/PuppetWidget.cpp                 |  2 ++
 widget/cocoa/nsChildView.mm             |  2 ++
 widget/gonk/nsWindow.cpp                | 16 ++++++-------
 widget/gtk/nsWindow.cpp                 | 31 ++++++++++++++++++++-----
 widget/gtk/nsWindow.h                   |  1 +
 widget/qt/nsWindow.cpp                  | 19 +++++++++++++--
 widget/qt/nsWindow.h                    |  1 +
 widget/windows/nsWindowGfx.cpp          |  2 ++
 10 files changed, 68 insertions(+), 21 deletions(-)

diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp
index 7ff13c62349c..47a29946ed61 100644
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1482,7 +1482,11 @@ nsComboboxControlFrame::Rollup(uint32_t aCount, bool aFlush,
     // The popup's visibility doesn't update until the minimize animation has
     // finished, so call UpdateWidgetGeometry to update it right away.
     nsViewManager* viewManager = mDropdownFrame->GetView()->GetViewManager();
-    viewManager->UpdateWidgetGeometry();
+    viewManager->UpdateWidgetGeometry(); // might destroy us
+  }
+
+  if (!weakFrame.IsAlive()) {
+    return consume;
   }
 
   if (aLastRolledUp) {
diff --git a/view/nsViewManager.cpp b/view/nsViewManager.cpp
index 4b2204578c3c..0664726baa09 100644
--- a/view/nsViewManager.cpp
+++ b/view/nsViewManager.cpp
@@ -708,15 +708,16 @@ void nsViewManager::InvalidateViews(nsView *aView)
 
 void nsViewManager::WillPaintWindow(nsIWidget* aWidget)
 {
-  if (aWidget) {
-    nsView* view = nsView::GetViewFor(aWidget);
-    LayerManager *manager = aWidget->GetLayerManager();
+  RefPtr widget(aWidget);
+  if (widget) {
+    nsView* view = nsView::GetViewFor(widget);
+    LayerManager* manager = widget->GetLayerManager();
     if (view &&
         (view->ForcedRepaint() || !manager->NeedsWidgetInvalidation())) {
       ProcessPendingUpdates();
       // Re-get the view pointer here since the ProcessPendingUpdates might have
       // destroyed it during CallWillPaintOnObservers.
-      view = nsView::GetViewFor(aWidget);
+      view = nsView::GetViewFor(widget);
       if (view) {
         view->SetForcedRepaint(false);
       }
diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp
index 631ca29d9cc4..1d5589296a20 100644
--- a/widget/PuppetWidget.cpp
+++ b/widget/PuppetWidget.cpp
@@ -1030,6 +1030,8 @@ PuppetWidget::Paint()
   mDirtyRegion.SetEmpty();
   mPaintTask.Revoke();
 
+  RefPtr strongThis(this);
+
   GetCurrentWidgetListener()->WillPaintWindow(this);
 
   if (GetCurrentWidgetListener()) {
diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm
index c62113cd6f0f..bedce33943c9 100644
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -3986,6 +3986,8 @@ NSEvent* gLastDragMouseDownEvent = nil;
 
 - (void)viewWillDraw
 {
+  nsAutoRetainCocoaObject kungFuDeathGrip(self);
+
   if (mGeckoChild) {
     // The OS normally *will* draw our NSWindow, no matter what we do here.
     // But Gecko can delete our parent widget(s) (along with mGeckoChild)
diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp
index c44a9277f795..ffec3cc88f2c 100644
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -105,7 +105,7 @@ nsWindow::DoDraw(void)
         return;
     }
 
-    nsWindow *targetWindow = (nsWindow *)windows[0];
+    RefPtr targetWindow = (nsWindow *)windows[0];
     while (targetWindow->GetLastChild()) {
         targetWindow = (nsWindow *)targetWindow->GetLastChild();
     }
@@ -115,15 +115,15 @@ nsWindow::DoDraw(void)
         listener->WillPaintWindow(targetWindow);
     }
 
-    LayerManager* lm = targetWindow->GetLayerManager();
-    if (mozilla::layers::LayersBackend::LAYERS_CLIENT == lm->GetBackendType()) {
-        // No need to do anything, the compositor will handle drawing
-    } else {
-        NS_RUNTIMEABORT("Unexpected layer manager type");
-    }
-
     listener = targetWindow->GetWidgetListener();
     if (listener) {
+        LayerManager* lm = targetWindow->GetLayerManager();
+        if (mozilla::layers::LayersBackend::LAYERS_CLIENT == lm->GetBackendType()) {
+            // No need to do anything, the compositor will handle drawing
+        } else {
+            NS_RUNTIMEABORT("Unexpected layer manager type");
+        }
+
         listener->DidPaintWindow();
     }
 }
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
index 08915ab80ad5..6d1931e3d558 100644
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -552,6 +552,12 @@ nsWindow::MaybeDispatchResized()
     }
 }
 
+nsIWidgetListener*
+nsWindow::GetListener()
+{
+    return mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
+}
+
 nsresult
 nsWindow::DispatchEvent(WidgetGUIEvent* aEvent, nsEventStatus& aStatus)
 {
@@ -560,8 +566,7 @@ nsWindow::DispatchEvent(WidgetGUIEvent* aEvent, nsEventStatus& aStatus)
                     "something", 0);
 #endif
     aStatus = nsEventStatus_eIgnore;
-    nsIWidgetListener* listener =
-        mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
+    nsIWidgetListener* listener = GetListener();
     if (listener) {
       aStatus = listener->HandleEvent(aEvent, mUseAttachedEvents);
     }
@@ -2119,8 +2124,7 @@ nsWindow::OnExposeEvent(cairo_t *cr)
     if (!mGdkWindow || mIsFullyObscured || !mHasMappedToplevel)
         return FALSE;
 
-    nsIWidgetListener *listener =
-        mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
+    nsIWidgetListener *listener = GetListener();
     if (!listener)
         return FALSE;
 
@@ -2149,6 +2153,8 @@ nsWindow::OnExposeEvent(cairo_t *cr)
         clientLayers->SendInvalidRegion(region.ToUnknownRegion());
     }
 
+    RefPtr strongThis(this);
+
     // Dispatch WillPaintWindow notification to allow scripts etc. to run
     // before we paint
     {
@@ -2161,8 +2167,7 @@ nsWindow::OnExposeEvent(cairo_t *cr)
 
         // Re-get the listener since the will paint notification might have
         // killed it.
-        listener =
-            mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
+        listener = GetListener();
         if (!listener)
             return FALSE;
     }
@@ -2223,6 +2228,13 @@ nsWindow::OnExposeEvent(cairo_t *cr)
     // If this widget uses OMTC...
     if (GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
         listener->PaintWindow(this, region);
+
+        // Re-get the listener since the will paint notification might have
+        // killed it.
+        listener = GetListener();
+        if (!listener)
+            return TRUE;
+
         listener->DidPaintWindow();
         return TRUE;
     }
@@ -2293,6 +2305,13 @@ nsWindow::OnExposeEvent(cairo_t *cr)
         }
         AutoLayerManagerSetup setupLayerManager(this, ctx, layerBuffering);
         painted = listener->PaintWindow(this, region);
+
+        // Re-get the listener since the will paint notification might have
+        // killed it.
+        listener = GetListener();
+        if (!listener)
+            return TRUE;
+
       }
     }
 
diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h
index ecc4c75ee2c4..f1ba102ab9da 100644
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -430,6 +430,7 @@ private:
                                    GdkWindow** aWindow, gint* aButton,
                                    gint* aRootX, gint* aRootY);
     void               ClearCachedResources();
+    nsIWidgetListener* GetListener();
 
     GtkWidget          *mShell;
     MozContainer       *mContainer;
diff --git a/widget/qt/nsWindow.cpp b/widget/qt/nsWindow.cpp
index cd60386a3aeb..f8c1f4858709 100644
--- a/widget/qt/nsWindow.cpp
+++ b/widget/qt/nsWindow.cpp
@@ -861,18 +861,28 @@ nsWindow::SetTitle(const nsAString& aTitle)
 
 // EVENTS
 
+nsIWidgetListener*
+nsWindow::GetPaintListener()
+{
+    return mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
+}
+
 void
 nsWindow::OnPaint()
 {
     LOGDRAW(("nsWindow::%s [%p]\n", __FUNCTION__, (void *)this));
-    nsIWidgetListener* listener =
-        mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
+    nsIWidgetListener* listener = GetPaintListener();
     if (!listener) {
         return;
     }
 
     listener->WillPaintWindow(this);
 
+    nsIWidgetListener* listener = GetPaintListener();
+    if (!listener) {
+        return;
+    }
+
     switch (GetLayerManager()->GetBackendType()) {
         case mozilla::layers::LayersBackend::LAYERS_CLIENT: {
             LayoutDeviceIntRegion region(
@@ -884,6 +894,11 @@ nsWindow::OnPaint()
             NS_ERROR("Invalid layer manager");
     }
 
+    nsIWidgetListener* listener = GetPaintListener();
+    if (!listener) {
+        return;
+    }
+
     listener->DidPaintWindow();
 }
 
diff --git a/widget/qt/nsWindow.h b/widget/qt/nsWindow.h
index 53a7b20ff5e9..8a32eb7e5cd9 100644
--- a/widget/qt/nsWindow.h
+++ b/widget/qt/nsWindow.h
@@ -253,6 +253,7 @@ private:
         bool needDispatch;
     } MozCachedMoveEvent;
 
+    nsIWidgetListener* GetPaintListener();
     bool               CheckForRollup(double aMouseX, double aMouseY, bool aIsWheel);
     void*              SetupPluginPort(void);
     nsresult           SetWindowIconList(const nsTArray &aIconList);
diff --git a/widget/windows/nsWindowGfx.cpp b/widget/windows/nsWindowGfx.cpp
index d2829dfc8002..33aa29e6d88c 100644
--- a/widget/windows/nsWindowGfx.cpp
+++ b/widget/windows/nsWindowGfx.cpp
@@ -276,6 +276,8 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel)
     clientLayerManager->SendInvalidRegion(region);
   }
 
+  RefPtr strongThis(this);
+
   nsIWidgetListener* listener = GetPaintListener();
   if (listener) {
     listener->WillPaintWindow(this);

From 1d3df2ccde81264de1c550348e0405eafe99acac Mon Sep 17 00:00:00 2001
From: Ben Tian 
Date: Fri, 6 May 2016 16:09:03 +0800
Subject: [PATCH 37/56] Bug 1261499 - Make nsContentUtils::AddScriptRunner
 return void, r=khuey

---
 dom/base/nsContentUtils.cpp                | 15 +++++++--------
 dom/base/nsContentUtils.h                  |  5 ++---
 dom/base/nsDocument.cpp                    | 10 +---------
 dom/html/nsTextEditorState.cpp             |  5 ++---
 dom/plugins/base/nsPluginInstanceOwner.cpp |  3 ++-
 layout/forms/nsComboboxControlFrame.cpp    |  3 +--
 layout/forms/nsTextControlFrame.cpp        |  7 +------
 7 files changed, 16 insertions(+), 32 deletions(-)

diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index a11dcb8ea98b..317a47481610 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -5029,28 +5029,27 @@ nsContentUtils::WarnScriptWasIgnored(nsIDocument* aDocument)
 }
 
 /* static */
-bool
+void
 nsContentUtils::AddScriptRunner(already_AddRefed aRunnable)
 {
   nsCOMPtr runnable = aRunnable;
   if (!runnable) {
-    return false;
+    return;
   }
 
   if (sScriptBlockerCount) {
-    return sBlockedScriptRunners->AppendElement(runnable.forget()) != nullptr;
+    sBlockedScriptRunners->AppendElement(runnable.forget());
+    return;
   }
-  
-  runnable->Run();
 
-  return true;
+  runnable->Run();
 }
 
 /* static */
-bool
+void
 nsContentUtils::AddScriptRunner(nsIRunnable* aRunnable) {
   nsCOMPtr runnable = aRunnable;
-  return AddScriptRunner(runnable.forget());
+  AddScriptRunner(runnable.forget());
 }
 
 /* static */
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index 890287ac8fba..2359acc66497 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -1606,10 +1606,9 @@ public:
    *                   scripts. Passing null is allowed and results in nothing
    *                   happening. It is also allowed to pass an object that
    *                   has not yet been AddRefed.
-   * @return false on out of memory, true otherwise.
    */
-  static bool AddScriptRunner(already_AddRefed aRunnable);
-  static bool AddScriptRunner(nsIRunnable* aRunnable);
+  static void AddScriptRunner(already_AddRefed aRunnable);
+  static void AddScriptRunner(nsIRunnable* aRunnable);
 
   /**
    * Returns true if it's safe to execute content script and false otherwise.
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index 89a11b8a1c54..ffe5aa7d447d 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -9082,16 +9082,8 @@ nsDocument::BlockOnload()
       // block onload only when there are no script blockers.
       ++mAsyncOnloadBlockCount;
       if (mAsyncOnloadBlockCount == 1) {
-        bool success = nsContentUtils::AddScriptRunner(
+        nsContentUtils::AddScriptRunner(
           NewRunnableMethod(this, &nsDocument::AsyncBlockOnload));
-
-        // The script runner shouldn't fail to add. But if somebody broke
-        // something and it does, we'll thrash at 100% cpu forever. The best
-        // response is just to ignore the onload blocking request. See bug 579535.
-        if (!success) {
-          NS_WARNING("Disaster! Onload blocking script runner failed to add - expect bad things!");
-          mAsyncOnloadBlockCount = 0;
-        }
       }
       return;
     }
diff --git a/dom/html/nsTextEditorState.cpp b/dom/html/nsTextEditorState.cpp
index 7bbb15f00a3e..e560dfe1a981 100644
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -1196,9 +1196,8 @@ nsTextEditorState::BindToFrame(nsTextControlFrame* aFrame)
       // otherwise, inherit the content node's direction
     }
 
-    if (!nsContentUtils::AddScriptRunner(
-          new PrepareEditorEvent(*this, content, currentValue)))
-      return NS_ERROR_OUT_OF_MEMORY;
+    nsContentUtils::AddScriptRunner(
+      new PrepareEditorEvent(*this, content, currentValue));
   }
 
   return NS_OK;
diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp
index 4207cbc5c187..13ecbb4f1897 100644
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -159,7 +159,8 @@ nsPluginInstanceOwner::NotifyPaintWaiter(nsDisplayListBuilder* aBuilder)
     nsCOMPtr event = new AsyncPaintWaitEvent(content, false);
     // Run this event as soon as it's safe to do so, since listeners need to
     // receive it immediately
-    mWaitingForPaint = nsContentUtils::AddScriptRunner(event);
+    nsContentUtils::AddScriptRunner(event);
+    mWaitingForPaint = true;
   }
 }
 
diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp
index 47a29946ed61..1f74c70fc5e9 100644
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1012,8 +1012,7 @@ nsComboboxControlFrame::RedisplayText(int32_t aIndex)
 
     RefPtr event = new RedisplayTextEvent(this);
     mRedisplayTextEvent = event;
-    if (!nsContentUtils::AddScriptRunner(event))
-      mRedisplayTextEvent.Forget();
+    nsContentUtils::AddScriptRunner(event);
   }
   return rv;
 }
diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp
index 7ca99e44eca8..f5f1a5d8a69a 100644
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -394,12 +394,7 @@ nsTextControlFrame::CreateAnonymousContent(nsTArray& aElements)
     }
     initializer = new EditorInitializer(this);
     Properties().Set(TextControlInitializer(),initializer);
-    if (!nsContentUtils::AddScriptRunner(initializer)) {
-      initializer->Revoke(); // paranoia
-      Properties().Delete(TextControlInitializer());
-      delete initializer;
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
+    nsContentUtils::AddScriptRunner(initializer);
   }
 
   return NS_OK;

From 79b656f376726e71066699d1571fd6b586441c31 Mon Sep 17 00:00:00 2001
From: Ben Tian 
Date: Fri, 6 May 2016 16:13:45 +0800
Subject: [PATCH 38/56] Bug 1261499 - [cleanup] Remove trailing spaces in
 nsContentUtils.{h,cpp}, r=khuey

---
 dom/base/nsContentUtils.cpp | 52 ++++++++++++++++++-------------------
 dom/base/nsContentUtils.h   | 12 ++++-----
 2 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 317a47481610..bf18c98fea78 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -668,7 +668,7 @@ nsContentUtils::InitializeModifierStrings()
     rv = bundleService->CreateBundle( "chrome://global-platform/locale/platformKeys.properties",
                                       getter_AddRefs(bundle));
   }
-  
+
   NS_ASSERTION(NS_SUCCEEDED(rv) && bundle, "chrome://global/locale/platformKeys.properties could not be loaded");
   nsXPIDLString shiftModifier;
   nsXPIDLString metaModifier;
@@ -691,7 +691,7 @@ nsContentUtils::InitializeModifierStrings()
   sOSText = new nsString(osModifier);
   sAltText = new nsString(altModifier);
   sControlText = new nsString(controlModifier);
-  sModifierSeparator = new nsString(modifierSeparator);  
+  sModifierSeparator = new nsString(modifierSeparator);
 }
 
 // Because of SVG/SMIL we have several atoms mapped to the same
@@ -1309,14 +1309,14 @@ nsContentUtils::SplitMimeType(const nsAString& aValue, nsString& aType,
   aType.StripWhitespace();
 }
 
-nsresult 
+nsresult
 nsContentUtils::IsUserIdle(uint32_t aRequestedIdleTimeInMS, bool* aUserIsIdle)
 {
   nsresult rv;
-  nsCOMPtr idleService = 
+  nsCOMPtr idleService =
     do_GetService("@mozilla.org/widget/idleservice;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
-    
+
   uint32_t idleTimeInMS;
   rv = idleService->GetIdleTime(&idleTimeInMS);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -1568,7 +1568,7 @@ bool nsContentUtils::IsAlphanumeric(uint32_t aChar)
 
   return (cat == nsIUGenCategory::kLetter || cat == nsIUGenCategory::kNumber);
 }
- 
+
 // static
 bool nsContentUtils::IsAlphanumericAt(const nsTextFragment* aFrag, uint32_t aOffset)
 {
@@ -1914,13 +1914,13 @@ nsContentUtils::Shutdown()
 
   delete sShiftText;
   sShiftText = nullptr;
-  delete sControlText;  
+  delete sControlText;
   sControlText = nullptr;
-  delete sMetaText;  
+  delete sMetaText;
   sMetaText = nullptr;
   delete sOSText;
   sOSText = nullptr;
-  delete sAltText;  
+  delete sAltText;
   sAltText = nullptr;
   delete sModifierSeparator;
   sModifierSeparator = nullptr;
@@ -2344,7 +2344,7 @@ nsContentUtils::ComparePoints(nsINode* aParent1, int32_t aOffset1,
 
   uint32_t pos1 = parents1.Length() - 1;
   uint32_t pos2 = parents2.Length() - 1;
-  
+
   bool disconnected = parents1.ElementAt(pos1) != parents2.ElementAt(pos2);
   if (aDisconnected) {
     *aDisconnected = disconnected;
@@ -2366,7 +2366,7 @@ nsContentUtils::ComparePoints(nsINode* aParent1, int32_t aOffset1,
     parent = child1;
   }
 
-  
+
   // The parent chains never differed, so one of the nodes is an ancestor of
   // the other
 
@@ -2803,7 +2803,7 @@ nsContentUtils::CheckQName(const nsAString& aQualifiedName,
   const char* colon = nullptr;
   const char16_t* begin = aQualifiedName.BeginReading();
   const char16_t* end = aQualifiedName.EndReading();
-  
+
   int result = MOZ_XMLCheckQName(reinterpret_cast(begin),
                                  reinterpret_cast(end),
                                  aNamespaceAware, &colon);
@@ -3867,7 +3867,7 @@ Element *
 nsContentUtils::MatchElementId(nsIContent *aContent, const nsAString& aId)
 {
   NS_PRECONDITION(!aId.IsEmpty(), "Will match random elements");
-  
+
   // ID attrs are generally stored as atoms, so just atomize this up front
   nsCOMPtr id(NS_Atomize(aId));
   if (!id) {
@@ -3959,8 +3959,8 @@ nsContentUtils::RegisterShutdownObserver(nsIObserver* aObserver)
   nsCOMPtr observerService =
     mozilla::services::GetObserverService();
   if (observerService) {
-    observerService->AddObserver(aObserver, 
-                                 NS_XPCOM_SHUTDOWN_OBSERVER_ID, 
+    observerService->AddObserver(aObserver,
+                                 NS_XPCOM_SHUTDOWN_OBSERVER_ID,
                                  false);
   }
 }
@@ -4274,7 +4274,7 @@ nsContentUtils::CreateContextualFragment(nsINode* aContextNode,
   if (isHTML) {
     RefPtr frag =
       new DocumentFragment(document->NodeInfoManager());
-    
+
     nsCOMPtr contextAsContent = do_QueryInterface(aContextNode);
     if (contextAsContent && !contextAsContent->IsElement()) {
       contextAsContent = contextAsContent->GetParent();
@@ -4283,7 +4283,7 @@ nsContentUtils::CreateContextualFragment(nsINode* aContextNode,
         contextAsContent = nullptr;
       }
     }
-    
+
     if (contextAsContent && !contextAsContent->IsHTMLElement(nsGkAtoms::html)) {
       aRv = ParseFragmentHTML(aFragment, frag,
                               contextAsContent->NodeInfo()->NameAtom(),
@@ -4695,7 +4695,7 @@ nsContentUtils::IsInSameAnonymousTree(const nsINode* aNode,
                   "Must have a node to work with");
   NS_PRECONDITION(aContent,
                   "Must have a content to work with");
-  
+
   if (!aNode->IsNodeOfType(nsINode::eCONTENT)) {
     /**
      * The root isn't an nsIContent, so it's a document or attribute.  The only
@@ -5113,14 +5113,14 @@ nsContentUtils::PerformMainThreadMicroTaskCheckpoint()
   nsDOMMutationObserver::HandleMutations();
 }
 
-/* 
+/*
  * Helper function for nsContentUtils::ProcessViewportInfo.
  *
  * Handles a single key=value pair. If it corresponds to a valid viewport
  * attribute, add it to the document header data. No validation is done on the
  * value itself (this is done at display time).
  */
-static void ProcessViewportToken(nsIDocument *aDocument, 
+static void ProcessViewportToken(nsIDocument *aDocument,
                                  const nsAString &token) {
 
   /* Iterators. */
@@ -5366,7 +5366,7 @@ nsContentUtils::CheckForSubFrameDrop(nsIDragSession* aDragSession,
   if (!target) {
     return true;
   }
-  
+
   nsIDocument* targetDoc = target->OwnerDoc();
   nsPIDOMWindowOuter* targetWin = targetDoc->GetWindow();
   if (!targetWin) {
@@ -5831,7 +5831,7 @@ nsContentUtils::GetUTFOrigin(nsIURI* aURI, nsAString& aOrigin)
   else {
     aOrigin.AssignLiteral("null");
   }
-  
+
   return NS_OK;
 }
 
@@ -6039,7 +6039,7 @@ nsContentUtils::MatchClassNames(nsIContent* aContent, int32_t aNamespaceID,
   if (!classAttr) {
     return false;
   }
-  
+
   // need to match *all* of the classes
   ClassMatchingInfo* info = static_cast(aData);
   uint32_t length = info->mClasses.Length();
@@ -6054,7 +6054,7 @@ nsContentUtils::MatchClassNames(nsIContent* aContent, int32_t aNamespaceID,
       return false;
     }
   }
-  
+
   return true;
 }
 
@@ -6341,10 +6341,10 @@ nsContentUtils::AllowXULXBLForPrincipal(nsIPrincipal* aPrincipal)
   if (IsSystemPrincipal(aPrincipal)) {
     return true;
   }
-  
+
   nsCOMPtr princURI;
   aPrincipal->GetURI(getter_AddRefs(princURI));
-  
+
   return princURI &&
          ((sAllowXULXBL_for_file && SchemeIs(princURI, "file")) ||
           IsSitePermAllow(aPrincipal, "allowXULXBL"));
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index 2359acc66497..f53da62747e1 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -393,7 +393,7 @@ public:
    */
   static bool IsFirstLetterPunctuation(uint32_t aChar);
   static bool IsFirstLetterPunctuationAt(const nsTextFragment* aFrag, uint32_t aOffset);
- 
+
   /**
    * Returns true if aChar is of class Lu, Ll, Lt, Lm, Lo, Nd, Nl or No
    */
@@ -933,7 +933,7 @@ private:
                                         const char16_t** aParams,
                                         uint32_t aParamsLength,
                                         nsXPIDLString& aResult);
-  
+
 public:
   template
   static nsresult FormatLocalizedString(PropertiesFile aFile,
@@ -1949,7 +1949,7 @@ public:
   {
     return sIsPerformanceTimingEnabled;
   }
-  
+
   /*
    * Returns true if user timing API should print to console.
    */
@@ -2255,11 +2255,11 @@ public:
 
   /**
    * Function checks if the user is idle.
-   * 
+   *
    * @param aRequestedIdleTimeInMS    The idle observer's requested idle time.
-   * @param aUserIsIdle               boolean indicating if the user 
+   * @param aUserIsIdle               boolean indicating if the user
    *                                  is currently idle or not.   *
-   * @return NS_OK                    NS_OK returned if the requested idle service and 
+   * @return NS_OK                    NS_OK returned if the requested idle service and
    *                                  the current idle time were successfully obtained.
    *                                  NS_ERROR_FAILURE returned if the the requested
    *                                  idle service or the current idle were not obtained.

From 477adfcd7effb64e48fa66f77cb9eeb41dc0ca09 Mon Sep 17 00:00:00 2001
From: Randell Jesup 
Date: Wed, 11 May 2016 00:09:53 -0400
Subject: [PATCH 39/56] Bug 1271514: clean up threads in test_unlock_notify
 r=froydnj

MozReview-Commit-ID: EbCnWFzLMca
---
 storage/test/test_unlock_notify.cpp | 74 ++++++++++++++++++-----------
 1 file changed, 45 insertions(+), 29 deletions(-)

diff --git a/storage/test/test_unlock_notify.cpp b/storage/test/test_unlock_notify.cpp
index 47d49deac677..31f63a2f9550 100644
--- a/storage/test/test_unlock_notify.cpp
+++ b/storage/test/test_unlock_notify.cpp
@@ -37,12 +37,19 @@ public:
 
   void RunInBackground()
   {
-    (void)NS_NewThread(getter_AddRefs(mThread));
+    (void)NS_NewNamedThread("DatabaseLocker", getter_AddRefs(mThread));
     do_check_true(mThread);
 
     do_check_success(mThread->Dispatch(this, NS_DISPATCH_NORMAL));
   }
 
+  void Shutdown()
+  {
+    if (mThread) {
+      mThread->Shutdown();
+    }
+  }
+
   NS_IMETHOD Run()
   {
     mozilla::ReentrantMonitorAutoEnter lock(monitor);
@@ -165,17 +172,20 @@ test_step_locked_does_not_block_main_thread()
 
   RefPtr locker(new DatabaseLocker("SELECT * FROM test"));
   do_check_true(locker);
-  mozilla::ReentrantMonitorAutoEnter lock(locker->monitor);
-  locker->RunInBackground();
+  {
+    mozilla::ReentrantMonitorAutoEnter lock(locker->monitor);
+    locker->RunInBackground();
 
-  // Wait for the locker to notify us that it has locked the database properly.
-  locker->WaitFor(WRITE_LOCK);
+    // Wait for the locker to notify us that it has locked the database properly.
+    locker->WaitFor(WRITE_LOCK);
 
-  bool hasResult;
-  rv = stmt->ExecuteStep(&hasResult);
-  do_check_eq(rv, NS_ERROR_FILE_IS_LOCKED);
+    bool hasResult;
+    rv = stmt->ExecuteStep(&hasResult);
+    do_check_eq(rv, NS_ERROR_FILE_IS_LOCKED);
 
-  locker->Notify(TEST_DONE);
+    locker->Notify(TEST_DONE);
+  }
+  locker->Shutdown();
 }
 
 void
@@ -194,18 +204,21 @@ test_drop_index_does_not_loop()
   RefPtr tester =
     new DatabaseTester(db, "DROP INDEX unique_data");
   do_check_true(tester);
-  mozilla::ReentrantMonitorAutoEnter lock(tester->monitor);
-  tester->RunInBackground();
+  {
+    mozilla::ReentrantMonitorAutoEnter lock(tester->monitor);
+    tester->RunInBackground();
 
-  // Hold a read lock on the database, and then let the tester try to execute.
-  bool hasResult;
-  rv = stmt->ExecuteStep(&hasResult);
-  do_check_success(rv);
-  do_check_true(hasResult);
-  tester->Notify(READ_LOCK);
+    // Hold a read lock on the database, and then let the tester try to execute.
+    bool hasResult;
+    rv = stmt->ExecuteStep(&hasResult);
+    do_check_success(rv);
+    do_check_true(hasResult);
+    tester->Notify(READ_LOCK);
 
-  // Make sure the tester finishes its test before we move on.
-  tester->WaitFor(TEST_DONE);
+    // Make sure the tester finishes its test before we move on.
+    tester->WaitFor(TEST_DONE);
+  }
+  tester->Shutdown();
 }
 
 void
@@ -223,18 +236,21 @@ test_drop_table_does_not_loop()
 
   RefPtr tester(new DatabaseTester(db, "DROP TABLE test"));
   do_check_true(tester);
-  mozilla::ReentrantMonitorAutoEnter lock(tester->monitor);
-  tester->RunInBackground();
+  {
+    mozilla::ReentrantMonitorAutoEnter lock(tester->monitor);
+    tester->RunInBackground();
 
-  // Hold a read lock on the database, and then let the tester try to execute.
-  bool hasResult;
-  rv = stmt->ExecuteStep(&hasResult);
-  do_check_success(rv);
-  do_check_true(hasResult);
-  tester->Notify(READ_LOCK);
+    // Hold a read lock on the database, and then let the tester try to execute.
+    bool hasResult;
+    rv = stmt->ExecuteStep(&hasResult);
+    do_check_success(rv);
+    do_check_true(hasResult);
+    tester->Notify(READ_LOCK);
 
-  // Make sure the tester finishes its test before we move on.
-  tester->WaitFor(TEST_DONE);
+    // Make sure the tester finishes its test before we move on.
+    tester->WaitFor(TEST_DONE);
+  }
+  tester->Shutdown();
 }
 
 void (*gTests[])(void) = {

From 73a32768d1afb859502243323c32a6c7df84c842 Mon Sep 17 00:00:00 2001
From: Randell Jesup 
Date: Wed, 11 May 2016 00:11:40 -0400
Subject: [PATCH 40/56] Bug 1271402: name and cleanup DataStorage thread when
 running XPCshell r=froyd,dkeeler

MozReview-Commit-ID: 2brXgEcp91J
---
 netwerk/base/nsSocketTransportService2.cpp |  4 +---
 security/manager/ssl/DataStorage.cpp       | 12 ++++++++----
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/netwerk/base/nsSocketTransportService2.cpp b/netwerk/base/nsSocketTransportService2.cpp
index 1544fd441bb8..3c4a5cdf1ff1 100644
--- a/netwerk/base/nsSocketTransportService2.cpp
+++ b/netwerk/base/nsSocketTransportService2.cpp
@@ -550,7 +550,7 @@ nsSocketTransportService::Init()
         return NS_ERROR_UNEXPECTED;
 
     nsCOMPtr thread;
-    nsresult rv = NS_NewThread(getter_AddRefs(thread), this);
+    nsresult rv = NS_NewNamedThread("Socket Thread", getter_AddRefs(thread), this);
     if (NS_FAILED(rv)) return rv;
     
     {
@@ -820,8 +820,6 @@ nsSocketTransportService::MarkTheLastElementOfPendingQueue()
 NS_IMETHODIMP
 nsSocketTransportService::Run()
 {
-    PR_SetCurrentThreadName("Socket Thread");
-
 #ifdef MOZ_NUWA_PROCESS
     if (IsNuwaProcess()) {
         NuwaMarkCurrentThread(nullptr, nullptr);
diff --git a/security/manager/ssl/DataStorage.cpp b/security/manager/ssl/DataStorage.cpp
index 2059bb5f8d72..a74141966015 100644
--- a/security/manager/ssl/DataStorage.cpp
+++ b/security/manager/ssl/DataStorage.cpp
@@ -106,7 +106,7 @@ DataStorage::Init(bool& aDataWillPersist)
 
   nsresult rv;
   if (XRE_IsParentProcess()) {
-    rv = NS_NewThread(getter_AddRefs(mWorkerThread));
+    rv = NS_NewNamedThread("DataStorage", getter_AddRefs(mWorkerThread));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
@@ -148,9 +148,10 @@ DataStorage::Init(bool& aDataWillPersist)
   // dispatched, so we need to clean up on xpcom-shutdown.
   if (XRE_IsParentProcess()) {
     os->AddObserver(this, "profile-before-change", false);
-  } else {
-    os->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
   }
+  // In the Parent process, this is a backstop for xpcshell and other cases
+  // where profile-before-change might not get sent.
+  os->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
 
   // For test purposes, we can set the write timer to be very fast.
   mTimerDelay = Preferences::GetInt("test.datastorage.write_timer_ms",
@@ -864,8 +865,11 @@ DataStorage::Observe(nsISupports* aSubject, const char* aTopic,
   if (strcmp(aTopic, "last-pb-context-exited") == 0) {
     MutexAutoLock lock(mMutex);
     mPrivateDataTable.Clear();
-  } else if (strcmp(aTopic, "profile-before-change") == 0) {
+  } else if (strcmp(aTopic, "profile-before-change") == 0 ||
+             (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0 &&
+              XRE_IsParentProcess())) {
     MOZ_ASSERT(XRE_IsParentProcess());
+    // per bug 1271402, this should be safe to run multiple times
     {
       MutexAutoLock lock(mMutex);
       rv = AsyncWriteData(lock);

From 8e8681cc486c48d369c0c3698e44d0654e31ebde Mon Sep 17 00:00:00 2001
From: Cameron McCormack 
Date: Wed, 11 May 2016 14:03:34 +1000
Subject: [PATCH 41/56] Bug 1271510 - Part 1: Rename
 nsStyleOutline::mCachedOutlineWidth to mActualOutlineWidth. r=dholbert

---
 layout/style/nsStyleStruct.cpp | 22 +++++++++++-----------
 layout/style/nsStyleStruct.h   | 16 ++++++++++------
 2 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
index b2c5937d1392..c2cf5d7821b5 100644
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -518,7 +518,7 @@ nsChangeHint nsStyleBorder::CalcDifference(const nsStyleBorder& aOther) const
 nsStyleOutline::nsStyleOutline(StyleStructContext aContext)
   : mOutlineWidth(NS_STYLE_BORDER_WIDTH_MEDIUM, eStyleUnit_Enumerated)
   , mOutlineOffset(0)
-  , mCachedOutlineWidth(0)
+  , mActualOutlineWidth(0)
   , mOutlineColor(NS_RGB(0, 0, 0))
   , mOutlineStyle(NS_STYLE_BORDER_STYLE_NONE)
   , mTwipsPerPixel(aContext.DevPixelsToAppUnits(1))
@@ -537,7 +537,7 @@ nsStyleOutline::nsStyleOutline(const nsStyleOutline& aSrc)
   : mOutlineRadius(aSrc.mOutlineRadius)
   , mOutlineWidth(aSrc.mOutlineWidth)
   , mOutlineOffset(aSrc.mOutlineOffset)
-  , mCachedOutlineWidth(aSrc.mCachedOutlineWidth)
+  , mActualOutlineWidth(aSrc.mActualOutlineWidth)
   , mOutlineColor(aSrc.mOutlineColor)
   , mOutlineStyle(aSrc.mOutlineStyle)
   , mTwipsPerPixel(aSrc.mTwipsPerPixel)
@@ -549,25 +549,25 @@ void
 nsStyleOutline::RecalcData()
 {
   if (NS_STYLE_BORDER_STYLE_NONE == GetOutlineStyle()) {
-    mCachedOutlineWidth = 0;
+    mActualOutlineWidth = 0;
   } else {
     MOZ_ASSERT(mOutlineWidth.ConvertsToLength() ||
                mOutlineWidth.GetUnit() == eStyleUnit_Enumerated);
     // Clamp negative calc() to 0.
-    mCachedOutlineWidth =
+    mActualOutlineWidth =
       std::max(CalcCoord(mOutlineWidth,
                          StaticPresData::Get()->GetBorderWidthTable(), 3), 0);
-    mCachedOutlineWidth =
-      NS_ROUND_BORDER_TO_PIXELS(mCachedOutlineWidth, mTwipsPerPixel);
+    mActualOutlineWidth =
+      NS_ROUND_BORDER_TO_PIXELS(mActualOutlineWidth, mTwipsPerPixel);
   }
 }
 
 nsChangeHint nsStyleOutline::CalcDifference(const nsStyleOutline& aOther) const
 {
-  bool outlineWasVisible =
-    mCachedOutlineWidth > 0 && mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE;
-  bool outlineIsVisible = 
-    aOther.mCachedOutlineWidth > 0 && aOther.mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE;
+  bool outlineWasVisible = mActualOutlineWidth > 0 &&
+                           mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE;
+  bool outlineIsVisible  = aOther.mActualOutlineWidth > 0 &&
+                           aOther.mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE;
   if (outlineWasVisible != outlineIsVisible ||
       (outlineIsVisible && (mOutlineOffset != aOther.mOutlineOffset ||
                             mOutlineWidth != aOther.mOutlineWidth ||
@@ -586,7 +586,7 @@ nsChangeHint nsStyleOutline::CalcDifference(const nsStyleOutline& aOther) const
   if (mOutlineWidth != aOther.mOutlineWidth ||
       mOutlineOffset != aOther.mOutlineOffset ||
       mTwipsPerPixel != aOther.mTwipsPerPixel ||
-      mCachedOutlineWidth != aOther.mCachedOutlineWidth) {
+      mActualOutlineWidth != aOther.mActualOutlineWidth) {
     return nsChangeHint_NeutralChange;
   }
 
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
index 15a340c3fd15..1d3446f4fac5 100644
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1316,14 +1316,17 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline
 
   nsStyleCorners  mOutlineRadius; // [reset] coord, percent, calc
 
-  // Note that this is a specified value.  You can get the actual values
-  // with GetOutlineWidth.  You cannot get the computed value directly.
+  // This is the specified value of outline-width, but with length values
+  // computed to absolute.  mActualOutlineWidth stores the outline-width
+  // value used by layout.  (We must store mOutlineWidth for the same
+  // style struct resolution reasons that we do nsStyleBorder::mBorder;
+  // see that field's comment.)
   nsStyleCoord  mOutlineWidth;    // [reset] coord, enum (see nsStyleConsts.h)
   nscoord       mOutlineOffset;   // [reset]
 
   nscoord GetOutlineWidth() const
   {
-    return mCachedOutlineWidth;
+    return mActualOutlineWidth;
   }
 
   uint8_t GetOutlineStyle() const
@@ -1364,9 +1367,10 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline
   }
 
 protected:
-  // This value is the actual value, so it's rounded to the nearest device
-  // pixel.
-  nscoord       mCachedOutlineWidth;
+  // The actual value of outline-width is the computed value (an absolute
+  // length, forced to zero when outline-style is none) rounded to device
+  // pixels.  This is the value used by layout.
+  nscoord       mActualOutlineWidth;
 
   nscolor       mOutlineColor;    // [reset]
 

From f9bc9c5fd47636d457e1da4a59b41a4a127598e4 Mon Sep 17 00:00:00 2001
From: Cameron McCormack 
Date: Wed, 11 May 2016 14:03:34 +1000
Subject: [PATCH 42/56] Bug 1271510 - Part 2: Improve
 nsStyleOutline::CalcDifference to make better use of mActualOutlineWidth.
 r=dholbert

---
 layout/style/nsStyleStruct.cpp | 26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
index c2cf5d7821b5..fb67231afe8f 100644
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -564,29 +564,25 @@ nsStyleOutline::RecalcData()
 
 nsChangeHint nsStyleOutline::CalcDifference(const nsStyleOutline& aOther) const
 {
-  bool outlineWasVisible = mActualOutlineWidth > 0 &&
-                           mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE;
-  bool outlineIsVisible  = aOther.mActualOutlineWidth > 0 &&
-                           aOther.mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE;
-  if (outlineWasVisible != outlineIsVisible ||
-      (outlineIsVisible && (mOutlineOffset != aOther.mOutlineOffset ||
-                            mOutlineWidth != aOther.mOutlineWidth ||
-                            mTwipsPerPixel != aOther.mTwipsPerPixel))) {
+  if (mActualOutlineWidth != aOther.mActualOutlineWidth ||
+      (mActualOutlineWidth > 0 &&
+       mOutlineOffset != aOther.mOutlineOffset)) {
     return NS_CombineHint(nsChangeHint_UpdateOverflow,
                           nsChangeHint_SchedulePaint);
   }
 
-  if ((mOutlineStyle != aOther.mOutlineStyle) ||
-      (mOutlineColor != aOther.mOutlineColor) ||
-      (mOutlineRadius != aOther.mOutlineRadius)) {
-    return nsChangeHint_RepaintFrame;
+  if (mOutlineStyle != aOther.mOutlineStyle ||
+      mOutlineColor != aOther.mOutlineColor ||
+      mOutlineRadius != aOther.mOutlineRadius) {
+    if (mActualOutlineWidth > 0) {
+      return nsChangeHint_RepaintFrame;
+    }
+    return nsChangeHint_NeutralChange;
   }
 
-  // XXX Not exactly sure if we need to check the cached outline values.
   if (mOutlineWidth != aOther.mOutlineWidth ||
       mOutlineOffset != aOther.mOutlineOffset ||
-      mTwipsPerPixel != aOther.mTwipsPerPixel ||
-      mActualOutlineWidth != aOther.mActualOutlineWidth) {
+      mTwipsPerPixel != aOther.mTwipsPerPixel) {
     return nsChangeHint_NeutralChange;
   }
 

From 4ca33888b2661d8bf48fcd5c1d06ed09682abac1 Mon Sep 17 00:00:00 2001
From: Cameron McCormack 
Date: Wed, 11 May 2016 14:03:34 +1000
Subject: [PATCH 43/56] Bug 1271869 - Rename NS_STYLE_TEXT_ALIGN_DEFAULT to
 NS_STYLE_TEXT_ALIGN_START. r=dholbert

---
 layout/forms/nsFieldSetFrame.cpp  | 2 +-
 layout/generic/nsBlockFrame.cpp   | 2 +-
 layout/generic/nsLineLayout.cpp   | 4 ++--
 layout/style/nsCSSProps.cpp       | 4 ++--
 layout/style/nsRuleNode.cpp       | 6 +++---
 layout/style/nsStyleConsts.h      | 2 +-
 layout/style/nsStyleContext.cpp   | 2 +-
 layout/style/nsStyleStruct.cpp    | 2 +-
 layout/xul/tree/nsTreeColumns.cpp | 6 +++---
 9 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp
index 236181f88021..0389ccc26713 100644
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -587,7 +587,7 @@ nsFieldSetFrame::Reflow(nsPresContext*           aPresContext,
           align = NS_STYLE_TEXT_ALIGN_END;
         } else if (align == NS_STYLE_TEXT_ALIGN_RIGHT ||
                    align == NS_STYLE_TEXT_ALIGN_MOZ_RIGHT) {
-          align = NS_STYLE_TEXT_ALIGN_DEFAULT;
+          align = NS_STYLE_TEXT_ALIGN_START;
         }
       }
       switch (align) {
diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
index 861925b1fffb..c999f8278321 100644
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -1839,7 +1839,7 @@ IsAlignedLeft(uint8_t aAlignment,
 {
   return aFrame->IsSVGText() ||
          NS_STYLE_TEXT_ALIGN_LEFT == aAlignment ||
-         (((NS_STYLE_TEXT_ALIGN_DEFAULT == aAlignment &&
+         (((NS_STYLE_TEXT_ALIGN_START == aAlignment &&
            NS_STYLE_DIRECTION_LTR == aDirection) ||
           (NS_STYLE_TEXT_ALIGN_END == aAlignment &&
            NS_STYLE_DIRECTION_RTL == aDirection)) &&
diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp
index bd48e50303ca..967cc63caea0 100644
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -3139,7 +3139,7 @@ nsLineLayout::TextAlignLine(nsLineBox* aLine,
     textAlignTrue = mStyleText->mTextAlignLastTrue;
     if (mStyleText->mTextAlignLast == NS_STYLE_TEXT_ALIGN_AUTO) {
       if (textAlign == NS_STYLE_TEXT_ALIGN_JUSTIFY) {
-        textAlign = NS_STYLE_TEXT_ALIGN_DEFAULT;
+        textAlign = NS_STYLE_TEXT_ALIGN_START;
       }
     } else {
       textAlign = mStyleText->mTextAlignLast;
@@ -3201,7 +3201,7 @@ nsLineLayout::TextAlignLine(nsLineBox* aLine,
         MOZ_FALLTHROUGH;
       }
 
-      case NS_STYLE_TEXT_ALIGN_DEFAULT:
+      case NS_STYLE_TEXT_ALIGN_START:
         // default alignment is to start edge so do nothing
         break;
 
diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp
index d231c7a83996..5123ace02865 100644
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1975,7 +1975,7 @@ KTableEntry nsCSSProps::kTextAlignKTable[] = {
   { eCSSKeyword__moz_center, NS_STYLE_TEXT_ALIGN_MOZ_CENTER },
   { eCSSKeyword__moz_right, NS_STYLE_TEXT_ALIGN_MOZ_RIGHT },
   { eCSSKeyword__moz_left, NS_STYLE_TEXT_ALIGN_MOZ_LEFT },
-  { eCSSKeyword_start, NS_STYLE_TEXT_ALIGN_DEFAULT },
+  { eCSSKeyword_start, NS_STYLE_TEXT_ALIGN_START },
   { eCSSKeyword_end, NS_STYLE_TEXT_ALIGN_END },
   { eCSSKeyword_unsafe, NS_STYLE_TEXT_ALIGN_UNSAFE },
   { eCSSKeyword_match_parent, NS_STYLE_TEXT_ALIGN_MATCH_PARENT },
@@ -1988,7 +1988,7 @@ KTableEntry nsCSSProps::kTextAlignLastKTable[] = {
   { eCSSKeyword_right, NS_STYLE_TEXT_ALIGN_RIGHT },
   { eCSSKeyword_center, NS_STYLE_TEXT_ALIGN_CENTER },
   { eCSSKeyword_justify, NS_STYLE_TEXT_ALIGN_JUSTIFY },
-  { eCSSKeyword_start, NS_STYLE_TEXT_ALIGN_DEFAULT },
+  { eCSSKeyword_start, NS_STYLE_TEXT_ALIGN_START },
   { eCSSKeyword_end, NS_STYLE_TEXT_ALIGN_END },
   { eCSSKeyword_unsafe, NS_STYLE_TEXT_ALIGN_UNSAFE },
   { eCSSKeyword_UNKNOWN, -1 }
diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
index 250ff2531873..779d1b8782ba 100644
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -4451,7 +4451,7 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
                textAlignValue->GetIntValue()) {
     conditions.SetUncacheable();
     uint8_t parentAlign = parentText->mTextAlign;
-    text->mTextAlign = (NS_STYLE_TEXT_ALIGN_DEFAULT == parentAlign) ?
+    text->mTextAlign = (NS_STYLE_TEXT_ALIGN_START == parentAlign) ?
       NS_STYLE_TEXT_ALIGN_CENTER : parentAlign;
   } else if (eCSSUnit_Enumerated == textAlignValue->GetUnit() &&
              NS_STYLE_TEXT_ALIGN_MATCH_PARENT ==
@@ -4462,7 +4462,7 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
       uint8_t parentAlign = parentText->mTextAlign;
       uint8_t parentDirection = parent->StyleVisibility()->mDirection;
       switch (parentAlign) {
-        case NS_STYLE_TEXT_ALIGN_DEFAULT:
+        case NS_STYLE_TEXT_ALIGN_START:
           text->mTextAlign = parentDirection == NS_STYLE_DIRECTION_RTL ?
             NS_STYLE_TEXT_ALIGN_RIGHT : NS_STYLE_TEXT_ALIGN_LEFT;
           break;
@@ -4496,7 +4496,7 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
     SetDiscrete(*textAlignValue, text->mTextAlign, conditions,
                 SETDSC_ENUMERATED | SETDSC_UNSET_INHERIT,
                 parentText->mTextAlign,
-                NS_STYLE_TEXT_ALIGN_DEFAULT, 0, 0, 0, 0);
+                NS_STYLE_TEXT_ALIGN_START, 0, 0, 0, 0);
   }
 
   // text-align-last: enum, pair(enum), inherit, initial
diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h
index 9581dbaca598..e54a68b042d3 100644
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -799,7 +799,7 @@ enum class FillMode : uint32_t;
 #define NS_STYLE_RESIZE_VERTICAL                3
 
 // See nsStyleText
-#define NS_STYLE_TEXT_ALIGN_DEFAULT               0
+#define NS_STYLE_TEXT_ALIGN_START                 0
 #define NS_STYLE_TEXT_ALIGN_LEFT                  1
 #define NS_STYLE_TEXT_ALIGN_RIGHT                 2
 #define NS_STYLE_TEXT_ALIGN_CENTER                3
diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp
index 9fe339c9d315..8cc068dffa0a 100644
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -704,7 +704,7 @@ nsStyleContext::ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup)
         text->mTextAlign == NS_STYLE_TEXT_ALIGN_MOZ_RIGHT)
     {
       nsStyleText* uniqueText = GET_UNIQUE_STYLE_DATA(Text);
-      uniqueText->mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT;
+      uniqueText->mTextAlign = NS_STYLE_TEXT_ALIGN_START;
     }
   }
 
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
index fb67231afe8f..6266a9796ca6 100644
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -3524,7 +3524,7 @@ AreShadowArraysEqual(nsCSSShadowArray* lhs,
 //
 
 nsStyleText::nsStyleText(StyleStructContext aContext)
-  : mTextAlign(NS_STYLE_TEXT_ALIGN_DEFAULT)
+  : mTextAlign(NS_STYLE_TEXT_ALIGN_START)
   , mTextAlignLast(NS_STYLE_TEXT_ALIGN_AUTO)
   , mTextAlignTrue(false)
   , mTextAlignLastTrue(false)
diff --git a/layout/xul/tree/nsTreeColumns.cpp b/layout/xul/tree/nsTreeColumns.cpp
index 911cae095677..c6ee19342e5d 100644
--- a/layout/xul/tree/nsTreeColumns.cpp
+++ b/layout/xul/tree/nsTreeColumns.cpp
@@ -288,13 +288,13 @@ nsTreeColumn::Invalidate()
   const nsStyleText* textStyle = frame->StyleText();
 
   mTextAlignment = textStyle->mTextAlign;
-  // DEFAULT or END alignment sometimes means RIGHT
-  if ((mTextAlignment == NS_STYLE_TEXT_ALIGN_DEFAULT &&
+  // START or END alignment sometimes means RIGHT
+  if ((mTextAlignment == NS_STYLE_TEXT_ALIGN_START &&
        vis->mDirection == NS_STYLE_DIRECTION_RTL) ||
       (mTextAlignment == NS_STYLE_TEXT_ALIGN_END &&
        vis->mDirection == NS_STYLE_DIRECTION_LTR)) {
     mTextAlignment = NS_STYLE_TEXT_ALIGN_RIGHT;
-  } else if (mTextAlignment == NS_STYLE_TEXT_ALIGN_DEFAULT ||
+  } else if (mTextAlignment == NS_STYLE_TEXT_ALIGN_START ||
              mTextAlignment == NS_STYLE_TEXT_ALIGN_END) {
     mTextAlignment = NS_STYLE_TEXT_ALIGN_LEFT;
   }

From e4fd8744419bbb16cf83cc8ff62ce65720fc76d6 Mon Sep 17 00:00:00 2001
From: Matthew Gregan 
Date: Wed, 11 May 2016 17:01:23 +1200
Subject: [PATCH 44/56] Bug 1271866 - Drop NULL check from nestegg_read_packet.
  r=giles

---
 media/libnestegg/bug1271866.patch | 14 ++++++++++++++
 media/libnestegg/src/nestegg.c    |  3 ---
 media/libnestegg/update.sh        |  1 +
 3 files changed, 15 insertions(+), 3 deletions(-)
 create mode 100644 media/libnestegg/bug1271866.patch

diff --git a/media/libnestegg/bug1271866.patch b/media/libnestegg/bug1271866.patch
new file mode 100644
index 000000000000..93863ad9518b
--- /dev/null
+++ b/media/libnestegg/bug1271866.patch
@@ -0,0 +1,14 @@
+diff --git a/media/libnestegg/src/nestegg.c b/media/libnestegg/src/nestegg.c
+index b9d3391..b13b2ae 100644
+--- a/media/libnestegg/src/nestegg.c
++++ b/media/libnestegg/src/nestegg.c
+@@ -2333,9 +2333,6 @@ nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt)
+ 
+   *pkt = NULL;
+ 
+-  if (!ctx->ancestor)
+-    return -1;
+-
+   for (;;) {
+     r = ne_peek_element(ctx, &id, &size);
+     if (r != 1)
diff --git a/media/libnestegg/src/nestegg.c b/media/libnestegg/src/nestegg.c
index b9d33919fef2..b13b2ae2259d 100644
--- a/media/libnestegg/src/nestegg.c
+++ b/media/libnestegg/src/nestegg.c
@@ -2333,9 +2333,6 @@ nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt)
 
   *pkt = NULL;
 
-  if (!ctx->ancestor)
-    return -1;
-
   for (;;) {
     r = ne_peek_element(ctx, &id, &size);
     if (r != 1)
diff --git a/media/libnestegg/update.sh b/media/libnestegg/update.sh
index 2d97f3eaec48..48966498f350 100755
--- a/media/libnestegg/update.sh
+++ b/media/libnestegg/update.sh
@@ -24,4 +24,5 @@ if [ -n "$rev" ]; then
 else
   echo "Remember to update README_MOZILLA with the version details."
 fi
+patch -p3 < ./bug1271866.patch
 

From 283296d6097aa136e89709a1abdce51eb63bbede Mon Sep 17 00:00:00 2001
From: Makoto Kato 
Date: Fri, 6 May 2016 17:33:20 +0900
Subject: [PATCH 45/56] Bug 1258526 - Create SAPI object per speech to clear
 previous speech state at force. r=eeejay

When using the following script, stop method cannot clear pause state on SAPI backend.

speech.pause();
speech.stop();

Since SPF_PURGEBEFORESPEAK doesn't clear previous speech state, we should create SAPI object per speech instead of recycling it.


MozReview-Commit-ID: 2ajsTbauQpO

--HG--
extra : rebase_source : b72d3e1215e136f204afda18497b042112002995
---
 .../webspeech/synth/windows/SapiService.cpp   | 54 ++++++++++++-------
 .../webspeech/synth/windows/SapiService.h     |  2 +-
 2 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/dom/media/webspeech/synth/windows/SapiService.cpp b/dom/media/webspeech/synth/windows/SapiService.cpp
index 2337fb48c7d2..02a98d803d0b 100644
--- a/dom/media/webspeech/synth/windows/SapiService.cpp
+++ b/dom/media/webspeech/synth/windows/SapiService.cpp
@@ -160,10 +160,11 @@ SapiCallback::OnSpeechEvent(const SPEVENT& speechEvent)
 void __stdcall
 SapiService::SpeechEventCallback(WPARAM aWParam, LPARAM aLParam)
 {
-  RefPtr service = (SapiService*) aWParam;
+  RefPtr spVoice = (ISpVoice*) aWParam;
+  RefPtr service = (SapiService*) aLParam;
 
   SPEVENT speechEvent;
-  while (service->mSapiClient->GetEvents(1, &speechEvent, nullptr) == S_OK) {
+  while (spVoice->GetEvents(1, &speechEvent, nullptr) == S_OK) {
     for (size_t i = 0; i < service->mCallbacks.Length(); i++) {
       RefPtr callback = service->mCallbacks[i];
       if (callback->GetStreamNum() == speechEvent.ulStreamNum) {
@@ -208,11 +209,24 @@ SapiService::Init()
     return false;
   }
 
-  if (FAILED(CoCreateInstance(CLSID_SpVoice, nullptr, CLSCTX_ALL, IID_ISpVoice,
-                              getter_AddRefs(mSapiClient)))) {
+  // Get all the voices from sapi and register in the SynthVoiceRegistry
+  if (!RegisterVoices()) {
     return false;
   }
 
+  mInitialized = true;
+  return true;
+}
+
+already_AddRefed
+SapiService::InitSapiInstance()
+{
+  RefPtr spVoice;
+  if (FAILED(CoCreateInstance(CLSID_SpVoice, nullptr, CLSCTX_ALL, IID_ISpVoice,
+                              getter_AddRefs(spVoice)))) {
+    return nullptr;
+  }
+
   // Set interest for all the events we are interested in
   ULONGLONG eventMask =
     SPFEI(SPEI_START_INPUT_STREAM) |
@@ -221,21 +235,16 @@ SapiService::Init()
     SPFEI(SPEI_SENTENCE_BOUNDARY) |
     SPFEI(SPEI_END_INPUT_STREAM);
 
-  if (FAILED(mSapiClient->SetInterest(eventMask, eventMask))) {
-    return false;
-  }
-
-  // Get all the voices from sapi and register in the SynthVoiceRegistry
-  if (!RegisterVoices()) {
-    return false;
+  if (FAILED(spVoice->SetInterest(eventMask, eventMask))) {
+    return nullptr;
   }
 
   // Set the callback function for receiving the events
-  mSapiClient->SetNotifyCallbackFunction(
-    (SPNOTIFYCALLBACK*) SapiService::SpeechEventCallback, (WPARAM) this, 0);
+  spVoice->SetNotifyCallbackFunction(
+    (SPNOTIFYCALLBACK*) SapiService::SpeechEventCallback,
+    (WPARAM) spVoice.get(), (LPARAM) this);
 
-  mInitialized = true;
-  return true;
+  return spVoice.forget();
 }
 
 bool
@@ -331,11 +340,16 @@ SapiService::Speak(const nsAString& aText, const nsAString& aUri,
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  if (FAILED(mSapiClient->SetVoice(voiceToken))) {
+  RefPtr spVoice = InitSapiInstance();
+  if (!spVoice) {
     return NS_ERROR_FAILURE;
   }
 
-  if (FAILED(mSapiClient->SetVolume(static_cast(aVolume * 100)))) {
+  if (FAILED(spVoice->SetVoice(voiceToken))) {
+    return NS_ERROR_FAILURE;
+  }
+
+  if (FAILED(spVoice->SetVolume(static_cast(aVolume * 100)))) {
     return NS_ERROR_FAILURE;
   }
 
@@ -348,7 +362,7 @@ SapiService::Speak(const nsAString& aText, const nsAString& aUri,
   //  rate by the 10th root of 3"
   // https://msdn.microsoft.com/en-us/library/ee431826(v=vs.85).aspx
   long rate = aRate != 0 ? static_cast(10 * log10(aRate) / log10(3)) : 0;
-  if (FAILED(mSapiClient->SetRate(rate))) {
+  if (FAILED(spVoice->SetRate(rate))) {
     return NS_ERROR_FAILURE;
   }
 
@@ -370,7 +384,7 @@ SapiService::Speak(const nsAString& aText, const nsAString& aUri,
   xml.AppendLiteral("");
 
   RefPtr callback =
-    new SapiCallback(aTask, mSapiClient, textOffset, aText.Length());
+    new SapiCallback(aTask, spVoice, textOffset, aText.Length());
 
   // The last three parameters doesn't matter for an indirect service
   nsresult rv = aTask->Setup(callback, 0, 0, 0);
@@ -379,7 +393,7 @@ SapiService::Speak(const nsAString& aText, const nsAString& aUri,
   }
 
   ULONG streamNum;
-  if (FAILED(mSapiClient->Speak(xml.get(), SPF_ASYNC, &streamNum))) {
+  if (FAILED(spVoice->Speak(xml.get(), SPF_ASYNC, &streamNum))) {
     aTask->Setup(nullptr, 0, 0, 0);
     return NS_ERROR_FAILURE;
   }
diff --git a/dom/media/webspeech/synth/windows/SapiService.h b/dom/media/webspeech/synth/windows/SapiService.h
index 5216ab5653cb..8a5aa43594cf 100644
--- a/dom/media/webspeech/synth/windows/SapiService.h
+++ b/dom/media/webspeech/synth/windows/SapiService.h
@@ -43,11 +43,11 @@ public:
 private:
   virtual ~SapiService();
 
+  already_AddRefed InitSapiInstance();
   bool RegisterVoices();
 
   nsRefPtrHashtable mVoices;
   nsTArray> mCallbacks;
-  RefPtr mSapiClient;
 
   bool mInitialized;
 

From 5d418de2b6bbea58686a14624babd38cf58b7d4f Mon Sep 17 00:00:00 2001
From: Makoto Kato 
Date: Mon, 9 May 2016 10:40:06 +0900
Subject: [PATCH 46/56] Bug 1257441 - Remove arm detection for WinCE using
 MSVS. r=glandium

arm.h still have CPU feature detection for Microsoft Compiler that is used by WinCE.   Since we don't have the target for WinCE, we should remove it.

Also, even if you need it for Win32/arm that is Windows Mobile and Windows IOT in feature, this is unnecessary.  Win32/arm ABI requires thumb2+NEON at least.


MozReview-Commit-ID: 6dYjIRY0Suo

--HG--
extra : rebase_source : 34db8ed7d3d60bafdfc735b036e891554a0e56c5
---
 mozglue/build/arm.cpp | 91 +------------------------------------------
 mozglue/build/arm.h   | 17 --------
 2 files changed, 1 insertion(+), 107 deletions(-)

diff --git a/mozglue/build/arm.cpp b/mozglue/build/arm.cpp
index dff466a16e8c..74b856a8f69f 100644
--- a/mozglue/build/arm.cpp
+++ b/mozglue/build/arm.cpp
@@ -13,96 +13,7 @@
 // we don't compile one of these detection methods. The detection code here is
 // based on the CPU detection in libtheora.
 
-#  if defined(_MSC_VER)
-//For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.
-#    define WIN32_LEAN_AND_MEAN
-#    define WIN32_EXTRA_LEAN
-#    include 
-
-#    if !defined(MOZILLA_PRESUME_EDSP)
-static bool
-check_edsp(void)
-{
-#      if defined(MOZILLA_MAY_SUPPORT_EDSP)
-  __try
-  {
-    //PLD [r13]
-    __emit(0xF5DDF000);
-    return true;
-  }
-  __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION)
-  {
-    //Ignore exception.
-  }
-#      endif
-  return false;
-}
-#    endif // !MOZILLA_PRESUME_EDSP
-
-#    if !defined(MOZILLA_PRESUME_ARMV6)
-static bool
-check_armv6(void)
-{
-#      if defined(MOZILLA_MAY_SUPPORT_ARMV6)
-  __try
-  {
-    //SHADD8 r3,r3,r3
-    __emit(0xE6333F93);
-    return true;
-  }
-  __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION)
-  {
-    //Ignore exception.
-  }
-#      endif
-  return false;
-}
-#    endif // !MOZILLA_PRESUME_ARMV6
-
-#    if !defined(MOZILLA_PRESUME_ARMV7)
-static bool
-check_armv7(void)
-{
-#      if defined(MOZILLA_MAY_SUPPORT_ARMV7)
-  __try
-  {
-    // ARMv7 DMB (Data Memory Barrier) for stores (DMB.ST)
-    // The Data Memory Barrier existed before ARMv7 as a
-    // cp15 operation, but ARMv7 introduced a dedicated
-    // instruction, DMB.
-    emit(0xF57FF05E);
-    return true;
-  }
-  __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION)
-  {
-    //Ignore exception.
-  }
-#      endif
-  return false;
-}
-#    endif // !MOZILLA_PRESUME_ARMV7
-
-#    if !defined(MOZILLA_PRESUME_NEON)
-static bool
-check_neon(void)
-{
-#      if defined(MOZILLA_MAY_SUPPORT_NEON)
-  __try
-  {
-    //VORR q0,q0,q0
-    __emit(0xF2200150);
-    return true;
-  }
-  __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION)
-  {
-    //Ignore exception.
-  }
-#      endif
-  return false;
-}
-#    endif // !MOZILLA_PRESUME_NEON
-
-#  elif defined(__linux__) || defined(ANDROID)
+#  if defined(__linux__) || defined(ANDROID)
 #    include 
 #    include 
 #    include 
diff --git a/mozglue/build/arm.h b/mozglue/build/arm.h
index d09d7cc07d6e..e3379f67b098 100644
--- a/mozglue/build/arm.h
+++ b/mozglue/build/arm.h
@@ -80,23 +80,6 @@
 #    define MOZILLA_ARM_HAVE_CPUID_DETECTION 1
 #  endif
 
-#elif defined(_MSC_VER) && defined(_M_ARM)
-
-#  define MOZILLA_ARM_HAVE_CPUID_DETECTION 1
-  // _M_ARM on MSVC has current cpu architecture.
-#  define MOZILLA_ARM_ARCH _M_ARM
-
-  // MSVC only allows external asm for ARM, so we don't have to rely on
-  // compiler support.
-#  define MOZILLA_MAY_SUPPORT_EDSP 1
-#  if defined(HAVE_ARM_SIMD)
-#    define MOZILLA_MAY_SUPPORT_ARMV6 1
-#    define MOZILLA_MAY_SUPPORT_ARMV7 1
-#  endif
-#  if defined(HAVE_ARM_NEON)
-#    define MOZILLA_MAY_SUPPORT_NEON 1
-#  endif
-
 #endif
 
 namespace mozilla {

From 25f5af3107495d968d76ebedb3f4c06a4c39e855 Mon Sep 17 00:00:00 2001
From: Brad Lassey 
Date: Tue, 10 May 2016 23:50:55 -0700
Subject: [PATCH 47/56] bug 1269998 - Prompt users with pending crash reports
 to submit them r=mconley ui-r=shorlander

---
 browser/components/nsBrowserGlue.js           | 60 +++++++++++++
 .../en-US/chrome/browser/browser.properties   |  5 ++
 toolkit/crashreporter/CrashSubmit.jsm         | 85 +++++++++++++++++++
 3 files changed, 150 insertions(+)

diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js
index eec2e8285433..181526e35319 100644
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -124,6 +124,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "TabCrashHandler",
 if (AppConstants.MOZ_CRASHREPORTER) {
   XPCOMUtils.defineLazyModuleGetter(this, "PluginCrashReporter",
                                     "resource:///modules/ContentCrashHandlers.jsm");
+  XPCOMUtils.defineLazyModuleGetter(this, "CrashSubmit",
+                                    "resource://gre/modules/CrashSubmit.jsm");
+  XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
+                                    "resource://gre/modules/PluralForm.jsm");
+
 }
 
 XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() {
@@ -821,6 +826,57 @@ BrowserGlue.prototype = {
     }
   },
 
+  checkForPendingCrashReports: function() {
+    // We don't process crash reports older than 28 days, so don't bother submitting them
+    let numDays = 28;
+    if (AppConstants.MOZ_CRASHREPORTER) {
+      let dateLimit = new Date();
+      dateLimit.setDate(dateLimit.getDate() - numDays);
+      CrashSubmit.pendingIDsAsync(dateLimit).then(
+        function onSuccess(ids) {
+          let count = ids.length;
+          if (count) {
+            let win = RecentWindow.getMostRecentBrowserWindow();
+            let nb =  win.document.getElementById("global-notificationbox");
+            let notification = nb.getNotificationWithValue("pending-crash-reports");
+            if (notification) {
+              return;
+            }
+            let buttons = [
+              {
+                label: win.gNavigatorBundle.getString("pendingCrashReports.submitAll"),
+                callback: function() {
+                  ids.forEach(function(id) {
+                    CrashSubmit.submit(id, {extraExtraKeyVals: {"SubmittedFromInfobar": true}});
+                  });
+                }
+              },
+              {
+                label: win.gNavigatorBundle.getString("pendingCrashReports.ignoreAll"),
+                callback: function() {
+                  ids.forEach(function(id) {
+                    CrashSubmit.ignore(id);
+                  });
+                }
+              },
+              {
+                label: win.gNavigatorBundle.getString("pendingCrashReports.viewAll"),
+                callback: function() {
+                  win.openUILinkIn("about:crashes", "tab");
+                }
+              }
+            ];
+            nb.appendNotification(PluralForm.get(count,
+                                                 win.gNavigatorBundle.getString("pendingCrashReports.label")).replace("#1", count),
+                                  "pending-crash-reports",
+                                  "chrome://browser/skin/tab-crashed.svg",
+                                  nb.PRIORITY_INFO_HIGH, buttons);
+          }
+        }
+      );
+    }
+  },
+
   _onSafeModeRestart: function BG_onSafeModeRestart() {
     // prompt the user to confirm
     let strings = gBrowserBundle;
@@ -1071,6 +1127,10 @@ BrowserGlue.prototype = {
 
     this._checkForOldBuildUpdates();
 
+    if ("release" != AppConstants.MOZ_UPDATE_CHANNEL) {
+      this.checkForPendingCrashReports();
+    }
+
     this._firstWindowTelemetry(aWindow);
     this._firstWindowLoaded();
   },
diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties
index 8f132e4fef58..a0383802ab4d 100644
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -760,6 +760,11 @@ certErrorDetailsCertChain.label = Certificate chain:
 tabgroups.migration.anonGroup = Group %S
 tabgroups.migration.tabGroupBookmarkFolderName = Bookmarked Tab Groups
 
+pendingCrashReports.label = You have an unsubmitted crash report;You have #1 unsubmitted crash reports
+pendingCrashReports.viewAll = View
+pendingCrashReports.submitAll = Submit
+pendingCrashReports.ignoreAll = Ignore
+
 decoder.noCodecs.button = Learn how
 decoder.noCodecs.accesskey = L
 decoder.noCodecs.message = To play video, you may need to install Microsoft’s Media Feature Pack.
diff --git a/toolkit/crashreporter/CrashSubmit.jsm b/toolkit/crashreporter/CrashSubmit.jsm
index 110e39013320..bdb64d600185 100644
--- a/toolkit/crashreporter/CrashSubmit.jsm
+++ b/toolkit/crashreporter/CrashSubmit.jsm
@@ -11,6 +11,8 @@ Cu.importGlobalProperties(['File']);
 
 XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
                                   "resource://gre/modules/PromiseUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "OS",
+                                  "resource://gre/modules/osfile.jsm");
 
 this.EXPORTED_SYMBOLS = [
   "CrashSubmit"
@@ -23,6 +25,8 @@ const SUCCESS = "success";
 const FAILED  = "failed";
 const SUBMITTING = "submitting";
 
+const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
+
 var reportURL = null;
 var strings = null;
 var myListener = null;
@@ -475,6 +479,29 @@ this.CrashSubmit = {
     }
   },
 
+  /**
+   * Add a .dmg.ignore file along side the .dmp file to indicate that the user
+   * shouldn't be prompted to submit this crash report again.
+   *
+   * @param id
+   *        Filename (minus .dmp extension) of the report to ignore
+   */
+
+  ignore: function CrashSubmit_ignore(id) {
+    let [dump, extra, mem] = getPendingMinidump(id);
+    return new Promise(
+      function (resolve, reject) {
+        let promise = OS.File.open(dump.path + ".ignore", {create: true}, {unixFlags:OS.Constants.libc.O_CREAT});
+        promise.then(
+          function createSuccess(file) {
+            file.close();
+            resolve();
+          }
+        );
+      }
+    )
+  },
+
   /**
    * Get the list of pending crash IDs.
    *
@@ -485,6 +512,64 @@ this.CrashSubmit = {
     return getAllPendingMinidumpsIDs();
   },
 
+  /**
+   * Get the list of pending crash IDs, exluding those marked to be ignored
+   * @param maxFileDate
+   *     A Date object. Any files last modified before that date will be ignored
+   *
+   * @return a Promise that is fulfilled with an array of string, each
+   * being an ID as expected to be passed to submit() or ignore()
+   */
+  pendingIDsAsync: function CrashSubmit_pendingIDsAsync(maxFileDate) {
+    let promise = new Promise(function(resolve, reject) {
+      OS.File.stat(getDir("pending").path).then(
+        function onSuccess(info) {
+          if (info.isDir) {
+            let iterator = new OS.File.DirectoryIterator(getDir("pending").path);
+            let ids = [];
+            iterator.forEach(
+              function onEntry(file) {
+                if (file.name.endsWith(".dmp")) {
+                  return OS.File.exists(file.path + ".ignore").then(
+                    function onSuccess(ignoreExists) {
+                      if (!ignoreExists) {
+                        let id = file.name.slice(0, -4);
+                        if (UUID_REGEX.test(id)) {
+                          return OS.File.stat(file.path).then(
+                            function onSuccess(info) {
+                              if (info.lastAccessDate.valueOf() > maxFileDate.valueOf()) {
+                                ids.push(id);
+                              }
+                            }
+                          );
+                        }
+                      }
+                    }
+                  );
+                }
+              }
+            ).then(
+              function onSuccess() {
+                iterator.close();
+                resolve(ids);
+              },
+              function onError(err) {
+                iterator.close();
+                reject(err);
+              }
+            );
+          } else {
+            reject();
+          }
+        },
+        function onError(err) {
+          reject(err);
+        }
+      )
+    });
+    return promise;
+  },
+
   /**
    * Prune the saved dumps.
    */

From b6f35101af85bff8acffb71a7a13df3ba70a6ae8 Mon Sep 17 00:00:00 2001
From: Chris Pearce 
Date: Wed, 11 May 2016 16:49:24 +1200
Subject: [PATCH 48/56] Bug 1271883 - Add Widevine keysystem to sGMPCodecs.
 r=jwwang

I broke Widevine in 1271242 when I changed EMEDecoderModule::SupportsMimeType()
to call GMPDecoderModule::SupportsMimeType() specifying a GMP to use, as I
didn't add the widevine keysystem to the take of keysystems that we recognise
in GMPDecoderModule. So we're unable to create an EME MediaDataDecoder.

In order to make Widevine EME work again, we need the Widevine keysystem string
in sGMPCodecs in GMPDecoderModule.cpp.

MozReview-Commit-ID: 6bJwsoGYIyL

--HG--
extra : rebase_source : be42b1848f10e2f4414319ffa8fe507d46e88cbc
---
 dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp b/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp
index 510c0588947a..83f50fd39031 100644
--- a/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp
@@ -156,6 +156,7 @@ struct GMPCodecs {
 static GMPCodecs sGMPCodecs[] = {
   { "org.w3.clearkey", false, false },
   { "com.adobe.primetime", false, false },
+  { "com.widevine.alpha", false, false },
 };
 
 void

From a137695351b966d1679e7d1f9b3f9f30467be222 Mon Sep 17 00:00:00 2001
From: Jean-Yves Avenard 
Date: Wed, 11 May 2016 15:59:33 +1000
Subject: [PATCH 49/56] Bug 1271847: Only adjust the samples once we have a
 complete moof. r=kentuckyfriedtakahe

MozReview-Commit-ID: 5TO0d20uUhZ

--HG--
extra : rebase_source : 0c0f0250d4fac6f3ffca736b6d79c7e4301e964e
---
 media/libstagefright/binding/MoofParser.cpp | 103 ++++++++++----------
 1 file changed, 53 insertions(+), 50 deletions(-)

diff --git a/media/libstagefright/binding/MoofParser.cpp b/media/libstagefright/binding/MoofParser.cpp
index 7c2d66615dc7..c4fbea9cc5f3 100644
--- a/media/libstagefright/binding/MoofParser.cpp
+++ b/media/libstagefright/binding/MoofParser.cpp
@@ -346,6 +346,20 @@ MoofParser::ParseEncrypted(Box& aBox)
   }
 }
 
+class CtsComparator
+{
+public:
+  bool Equals(Sample* const aA, Sample* const aB) const
+  {
+    return aA->mCompositionRange.start == aB->mCompositionRange.start;
+  }
+  bool
+  LessThan(Sample* const aA, Sample* const aB) const
+  {
+    return aA->mCompositionRange.start < aB->mCompositionRange.start;
+  }
+};
+
 Moof::Moof(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf, uint64_t* aDecodeTime, bool aIsAudio)
   : mRange(aBox.Range())
   , mMaxRoundingError(35000)
@@ -356,6 +370,42 @@ Moof::Moof(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, Sinf&
     }
   }
   if (IsValid()) {
+    if (mIndex.Length()) {
+      // Ensure the samples are contiguous with no gaps.
+      nsTArray ctsOrder;
+      for (auto& sample : mIndex) {
+        ctsOrder.AppendElement(&sample);
+      }
+      ctsOrder.Sort(CtsComparator());
+
+      for (size_t i = 1; i < ctsOrder.Length(); i++) {
+        ctsOrder[i-1]->mCompositionRange.end = ctsOrder[i]->mCompositionRange.start;
+      }
+
+      // In MP4, the duration of a sample is defined as the delta between two decode
+      // timestamps. The operation above has updated the duration of each sample
+      // as a Sample's duration is mCompositionRange.end - mCompositionRange.start
+      // MSE's TrackBuffersManager expects dts that increased by the sample's
+      // duration, so we rewrite the dts accordingly.
+      int64_t presentationDuration =
+        ctsOrder.LastElement()->mCompositionRange.end
+        - ctsOrder[0]->mCompositionRange.start;
+      int64_t endDecodeTime =
+        aMdhd.ToMicroseconds((int64_t)*aDecodeTime - aEdts.mMediaStart)
+        + aMvhd.ToMicroseconds(aEdts.mEmptyOffset);
+      int64_t decodeDuration = endDecodeTime - mIndex[0].mDecodeTime;
+      float adjust = (float)decodeDuration / presentationDuration;
+      int64_t dtsOffset = mIndex[0].mDecodeTime;
+      int64_t compositionDuration = 0;
+      // Adjust the dts, ensuring that the new adjusted dts will never be greater
+      // than decodeTime (the next moof's decode start time).
+      for (auto& sample : mIndex) {
+        sample.mDecodeTime = dtsOffset + compositionDuration * adjust;
+        compositionDuration += sample.mCompositionRange.Length();
+      }
+      mTimeRange = Interval(ctsOrder[0]->mCompositionRange.start,
+          ctsOrder.LastElement()->mCompositionRange.end);
+    }
     ProcessCenc();
   }
 }
@@ -470,20 +520,6 @@ Moof::FixRounding(const Moof& aMoof) {
   }
 }
 
-class CtsComparator
-{
-public:
-  bool Equals(Sample* const aA, Sample* const aB) const
-  {
-    return aA->mCompositionRange.start == aB->mCompositionRange.start;
-  }
-  bool
-  LessThan(Sample* const aA, Sample* const aB) const
-  {
-    return aA->mCompositionRange.start < aB->mCompositionRange.start;
-  }
-};
-
 bool
 Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, uint64_t* aDecodeTime, bool aIsAudio)
 {
@@ -554,6 +590,8 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, u
     sample.mByteRange = MediaByteRange(offset, offset + sampleSize);
     offset += sampleSize;
 
+    sample.mDecodeTime =
+      aMdhd.ToMicroseconds((int64_t)decodeTime - aEdts.mMediaStart) + aMvhd.ToMicroseconds(aEdts.mEmptyOffset);
     sample.mCompositionRange = Interval(
       aMdhd.ToMicroseconds((int64_t)decodeTime + ctsOffset - aEdts.mMediaStart) + aMvhd.ToMicroseconds(aEdts.mEmptyOffset),
       aMdhd.ToMicroseconds((int64_t)decodeTime + ctsOffset + sampleDuration - aEdts.mMediaStart) + aMvhd.ToMicroseconds(aEdts.mEmptyOffset));
@@ -570,43 +608,8 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, u
   }
   mMaxRoundingError += aMdhd.ToMicroseconds(sampleCount);
 
-  nsTArray ctsOrder;
-  for (int i = 0; i < mIndex.Length(); i++) {
-    ctsOrder.AppendElement(&mIndex[i]);
-  }
-  ctsOrder.Sort(CtsComparator());
-
-  for (size_t i = 0; i < ctsOrder.Length(); i++) {
-    if (i + 1 < ctsOrder.Length()) {
-      ctsOrder[i]->mCompositionRange.end = ctsOrder[i + 1]->mCompositionRange.start;
-    }
-  }
-  // In MP4, the duration of a sample is defined as the delta between two decode
-  // timestamps. The operation above has updated the duration of each sample
-  // as a Sample's duration is mCompositionRange.end - mCompositionRange.start
-  // MSE's TrackBuffersManager expects dts that increased by the sample's
-  // duration, so we rewrite the dts accordingly.
-  int64_t presentationDuration = ctsOrder.LastElement()->mCompositionRange.end
-                                 - ctsOrder[0]->mCompositionRange.start;
-  int64_t decodeDuration = aMdhd.ToMicroseconds(decodeTime - *aDecodeTime);
-  float adjust = (float)decodeDuration / presentationDuration;
-  int64_t dtsOffset =
-    aMdhd.ToMicroseconds((int64_t)*aDecodeTime - aEdts.mMediaStart)
-    + aMvhd.ToMicroseconds(aEdts.mEmptyOffset);
-  int64_t compositionDuration = 0;
-  // Adjust the dts, ensuring that the new adjusted dts will never be greater
-  // than decodeTime (the next moof's decode start time).
-  for (auto& sample : mIndex) {
-    sample.mDecodeTime = dtsOffset + compositionDuration * adjust;
-    compositionDuration += sample.mCompositionRange.Length();
-  }
-  mTimeRange = Interval(ctsOrder[0]->mCompositionRange.start,
-      ctsOrder.LastElement()->mCompositionRange.end);
   *aDecodeTime = decodeTime;
-  MOZ_ASSERT(aMdhd.ToMicroseconds((int64_t)decodeTime - aEdts.mMediaStart)
-             + aMvhd.ToMicroseconds(aEdts.mEmptyOffset)
-             >= mIndex[mIndex.Length() -1].mDecodeTime,
-             "Adjusted dts is too high");
+
   return true;
 }
 

From 979a6fb7b7141c63f601234b6c27a74ad611488d Mon Sep 17 00:00:00 2001
From: Bob Owen 
Date: Tue, 10 May 2016 15:17:56 +0100
Subject: [PATCH 50/56] Bug 1271348: Only use LOGPIXELSY for calculating
 internal printing surface size on Windows. r=jimm

MozReview-Commit-ID: 9KUVyI0Oy07

--HG--
extra : rebase_source : 1fcbeebff29e1a0cfd77ac5abf5914bb7031cd86
---
 gfx/thebes/gfxWindowsSurface.cpp      |  7 +++++--
 widget/windows/nsPrintSettingsWin.cpp | 11 ++++++-----
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/gfx/thebes/gfxWindowsSurface.cpp b/gfx/thebes/gfxWindowsSurface.cpp
index 41cb047a21f2..de6d3f9a88b3 100644
--- a/gfx/thebes/gfxWindowsSurface.cpp
+++ b/gfx/thebes/gfxWindowsSurface.cpp
@@ -312,10 +312,13 @@ gfxWindowsSurface::GetSize() const
 {
     if (mForPrinting) {
         // On Windows we need to use the printable area of the page.
+        // Note: we only scale the printing using the LOGPIXELSY, so we use that
+        // when calculating the surface width as well as the height.
+        int32_t heightDPI = ::GetDeviceCaps(mDC, LOGPIXELSY);
         float width = (::GetDeviceCaps(mDC, HORZRES) * POINTS_PER_INCH_FLOAT)
-                      / ::GetDeviceCaps(mDC, LOGPIXELSX);
+                      / heightDPI;
         float height = (::GetDeviceCaps(mDC, VERTRES) * POINTS_PER_INCH_FLOAT)
-                       / ::GetDeviceCaps(mDC, LOGPIXELSY);
+                       / heightDPI;
         return mozilla::gfx::IntSize(width, height);
     }
 
diff --git a/widget/windows/nsPrintSettingsWin.cpp b/widget/windows/nsPrintSettingsWin.cpp
index 8641ca360649..8ff73a94f1f7 100644
--- a/widget/windows/nsPrintSettingsWin.cpp
+++ b/widget/windows/nsPrintSettingsWin.cpp
@@ -209,22 +209,23 @@ nsPrintSettingsWin::CopyFromNative(HDC aHdc, DEVMODEW* aDevMode)
   // page and don't set the unwriteable [sic] margins. Using the unwriteable
   // margins doesn't appear to work on Windows, but I am not sure if this is a
   // bug elsewhere in our code or a Windows quirk.
+  // Note: we only scale the printing using the LOGPIXELSY, so we use that
+  // when calculating the surface width as well as the height.
   int32_t printableWidthInDots = GetDeviceCaps(aHdc, HORZRES);
   int32_t printableHeightInDots = GetDeviceCaps(aHdc, VERTRES);
-  int32_t widthDPI = GetDeviceCaps(aHdc, LOGPIXELSX);
   int32_t heightDPI = GetDeviceCaps(aHdc, LOGPIXELSY);
 
   // Keep these values in portrait format, so we can reflect our own changes
   // to mOrientation.
   if (mOrientation == kPortraitOrientation) {
-    mPrintableWidthInInches = double(printableWidthInDots) / widthDPI;
+    mPrintableWidthInInches = double(printableWidthInDots) / heightDPI;
     mPrintableHeightInInches = double(printableHeightInDots) / heightDPI;
   } else {
-    mPrintableHeightInInches = double(printableWidthInDots) / widthDPI;
+    mPrintableHeightInInches = double(printableWidthInDots) / heightDPI;
     mPrintableWidthInInches = double(printableHeightInDots) / heightDPI;
   }
 
-  // Using Y to match existing code, X DPI should be the same for printing.
+  // Using Y to match existing code for print scaling calculations.
   mResolution = heightDPI;
 }
 
@@ -397,4 +398,4 @@ Tester::Tester()
 
 }
 Tester gTester;
-#endif
\ No newline at end of file
+#endif

From b4581e4e5231c6a8df3bd85a21b3b8ae5e002239 Mon Sep 17 00:00:00 2001
From: Jonathan Kew 
Date: Mon, 9 May 2016 18:02:45 +0100
Subject: [PATCH 51/56] Bug 1270878 - Factory method that creates a
 BundledFontEnumerator needs to ensure it is AddRef'd before being returned to
 the caller. r=bas

---
 gfx/thebes/gfxDWriteFontList.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp
index 695e2d9f985c..e2641a46e77b 100644
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -1821,6 +1821,7 @@ BundledFontLoader::CreateEnumeratorFromKey(
 {
     nsIFile *fontDir = *(nsIFile**)aCollectionKey;
     *aFontFileEnumerator = new BundledFontFileEnumerator(aFactory, fontDir);
+    NS_ADDREF(*aFontFileEnumerator);
     return S_OK;
 }
 

From bcf28c976da8e5ae07279726573200cf59ebac84 Mon Sep 17 00:00:00 2001
From: Jonathan Kew 
Date: Wed, 11 May 2016 09:02:52 +0100
Subject: [PATCH 52/56] Bug 1271262 - Enable graphite2 font shaping by default
 for all channels. r=jet

---
 modules/libpref/init/all.js | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index 38e2cbbd1bd6..3acbc9d501c9 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -703,11 +703,7 @@ pref("gfx.font_rendering.wordcache.charlimit", 32);
 // cache shaped word results
 pref("gfx.font_rendering.wordcache.maxentries", 10000);
 
-#ifdef RELEASE_BUILD
-pref("gfx.font_rendering.graphite.enabled", false);
-#else
 pref("gfx.font_rendering.graphite.enabled", true);
-#endif
 
 #ifdef XP_WIN
 pref("gfx.font_rendering.directwrite.force-enabled", false);

From 2995111984d9b960b65bb0aeb5938f9a45de9d19 Mon Sep 17 00:00:00 2001
From: Sebastian Hengst 
Date: Wed, 11 May 2016 10:10:28 +0200
Subject: [PATCH 53/56] Bug 1269998 - Prompt users with pending crash reports
 to submit them. r=eslint-fix

---
 toolkit/crashreporter/CrashSubmit.jsm | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/toolkit/crashreporter/CrashSubmit.jsm b/toolkit/crashreporter/CrashSubmit.jsm
index bdb64d600185..e881131f34b9 100644
--- a/toolkit/crashreporter/CrashSubmit.jsm
+++ b/toolkit/crashreporter/CrashSubmit.jsm
@@ -543,10 +543,12 @@ this.CrashSubmit = {
                             }
                           );
                         }
+                        return;
                       }
                     }
                   );
                 }
+                return;
               }
             ).then(
               function onSuccess() {

From daa1794d1a30f50271df6c6e84066b999ad7cb02 Mon Sep 17 00:00:00 2001
From: Nicolas Silva 
Date: Fri, 29 Apr 2016 10:14:29 +0200
Subject: [PATCH 54/56] Bug 1216658 - Ignore Gt3 dark themes and use light
 theme's color scheme for native widgets. r=karlt

---
 widget/gtk/nsLookAndFeel.cpp | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/widget/gtk/nsLookAndFeel.cpp b/widget/gtk/nsLookAndFeel.cpp
index 044f908652ab..c190becec8db 100644
--- a/widget/gtk/nsLookAndFeel.cpp
+++ b/widget/gtk/nsLookAndFeel.cpp
@@ -1095,7 +1095,19 @@ nsLookAndFeel::Init()
     // Gtk manages a screen's CSS in the settings object so we
     // ask Gtk to create it explicitly. Otherwise we may end up
     // with wrong color theme, see Bug 972382
-    (void)gtk_settings_get_for_screen(gdk_screen_get_default());
+    GtkSettings *settings = gtk_settings_get_for_screen(gdk_screen_get_default());
+
+    // Disable dark theme because it interacts poorly with widget styling in
+    // web content (see bug 1216658).
+    // To avoid triggering reload of theme settings unnecessarily, only set the
+    // setting when necessary.
+    const gchar* dark_setting = "gtk-application-prefer-dark-theme";
+    gboolean dark;
+    g_object_get(settings, dark_setting, &dark, nullptr);
+
+    if (dark) {
+        g_object_set(settings, dark_setting, FALSE, nullptr);
+    }
 
     GtkWidgetPath *path = gtk_widget_path_new();
     gtk_widget_path_append_type(path, GTK_TYPE_WINDOW);

From b54155769c0bb1f3c262e9d1d7c77a792b203b5a Mon Sep 17 00:00:00 2001
From: Sebastian Hengst 
Date: Wed, 11 May 2016 10:44:49 +0200
Subject: [PATCH 55/56] Backed out changeset eb3aee42c9a8 (bug 1269998) because
 it didn't fix the eslint bustage. r=backout

---
 toolkit/crashreporter/CrashSubmit.jsm | 2 --
 1 file changed, 2 deletions(-)

diff --git a/toolkit/crashreporter/CrashSubmit.jsm b/toolkit/crashreporter/CrashSubmit.jsm
index e881131f34b9..bdb64d600185 100644
--- a/toolkit/crashreporter/CrashSubmit.jsm
+++ b/toolkit/crashreporter/CrashSubmit.jsm
@@ -543,12 +543,10 @@ this.CrashSubmit = {
                             }
                           );
                         }
-                        return;
                       }
                     }
                   );
                 }
-                return;
               }
             ).then(
               function onSuccess() {

From d0b575b3af320fde75fb8e0fc4904792483a1d9c Mon Sep 17 00:00:00 2001
From: Sebastian Hengst 
Date: Wed, 11 May 2016 10:44:57 +0200
Subject: [PATCH 56/56] Backed out changeset 756948b3ac0f (bug 1269998) for
 unexpected file access of crashreporter.ini on startup. r=backout

---
 browser/components/nsBrowserGlue.js           | 60 -------------
 .../en-US/chrome/browser/browser.properties   |  5 --
 toolkit/crashreporter/CrashSubmit.jsm         | 85 -------------------
 3 files changed, 150 deletions(-)

diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js
index 181526e35319..eec2e8285433 100644
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -124,11 +124,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "TabCrashHandler",
 if (AppConstants.MOZ_CRASHREPORTER) {
   XPCOMUtils.defineLazyModuleGetter(this, "PluginCrashReporter",
                                     "resource:///modules/ContentCrashHandlers.jsm");
-  XPCOMUtils.defineLazyModuleGetter(this, "CrashSubmit",
-                                    "resource://gre/modules/CrashSubmit.jsm");
-  XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
-                                    "resource://gre/modules/PluralForm.jsm");
-
 }
 
 XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() {
@@ -826,57 +821,6 @@ BrowserGlue.prototype = {
     }
   },
 
-  checkForPendingCrashReports: function() {
-    // We don't process crash reports older than 28 days, so don't bother submitting them
-    let numDays = 28;
-    if (AppConstants.MOZ_CRASHREPORTER) {
-      let dateLimit = new Date();
-      dateLimit.setDate(dateLimit.getDate() - numDays);
-      CrashSubmit.pendingIDsAsync(dateLimit).then(
-        function onSuccess(ids) {
-          let count = ids.length;
-          if (count) {
-            let win = RecentWindow.getMostRecentBrowserWindow();
-            let nb =  win.document.getElementById("global-notificationbox");
-            let notification = nb.getNotificationWithValue("pending-crash-reports");
-            if (notification) {
-              return;
-            }
-            let buttons = [
-              {
-                label: win.gNavigatorBundle.getString("pendingCrashReports.submitAll"),
-                callback: function() {
-                  ids.forEach(function(id) {
-                    CrashSubmit.submit(id, {extraExtraKeyVals: {"SubmittedFromInfobar": true}});
-                  });
-                }
-              },
-              {
-                label: win.gNavigatorBundle.getString("pendingCrashReports.ignoreAll"),
-                callback: function() {
-                  ids.forEach(function(id) {
-                    CrashSubmit.ignore(id);
-                  });
-                }
-              },
-              {
-                label: win.gNavigatorBundle.getString("pendingCrashReports.viewAll"),
-                callback: function() {
-                  win.openUILinkIn("about:crashes", "tab");
-                }
-              }
-            ];
-            nb.appendNotification(PluralForm.get(count,
-                                                 win.gNavigatorBundle.getString("pendingCrashReports.label")).replace("#1", count),
-                                  "pending-crash-reports",
-                                  "chrome://browser/skin/tab-crashed.svg",
-                                  nb.PRIORITY_INFO_HIGH, buttons);
-          }
-        }
-      );
-    }
-  },
-
   _onSafeModeRestart: function BG_onSafeModeRestart() {
     // prompt the user to confirm
     let strings = gBrowserBundle;
@@ -1127,10 +1071,6 @@ BrowserGlue.prototype = {
 
     this._checkForOldBuildUpdates();
 
-    if ("release" != AppConstants.MOZ_UPDATE_CHANNEL) {
-      this.checkForPendingCrashReports();
-    }
-
     this._firstWindowTelemetry(aWindow);
     this._firstWindowLoaded();
   },
diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties
index a0383802ab4d..8f132e4fef58 100644
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -760,11 +760,6 @@ certErrorDetailsCertChain.label = Certificate chain:
 tabgroups.migration.anonGroup = Group %S
 tabgroups.migration.tabGroupBookmarkFolderName = Bookmarked Tab Groups
 
-pendingCrashReports.label = You have an unsubmitted crash report;You have #1 unsubmitted crash reports
-pendingCrashReports.viewAll = View
-pendingCrashReports.submitAll = Submit
-pendingCrashReports.ignoreAll = Ignore
-
 decoder.noCodecs.button = Learn how
 decoder.noCodecs.accesskey = L
 decoder.noCodecs.message = To play video, you may need to install Microsoft’s Media Feature Pack.
diff --git a/toolkit/crashreporter/CrashSubmit.jsm b/toolkit/crashreporter/CrashSubmit.jsm
index bdb64d600185..110e39013320 100644
--- a/toolkit/crashreporter/CrashSubmit.jsm
+++ b/toolkit/crashreporter/CrashSubmit.jsm
@@ -11,8 +11,6 @@ Cu.importGlobalProperties(['File']);
 
 XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
                                   "resource://gre/modules/PromiseUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "OS",
-                                  "resource://gre/modules/osfile.jsm");
 
 this.EXPORTED_SYMBOLS = [
   "CrashSubmit"
@@ -25,8 +23,6 @@ const SUCCESS = "success";
 const FAILED  = "failed";
 const SUBMITTING = "submitting";
 
-const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
-
 var reportURL = null;
 var strings = null;
 var myListener = null;
@@ -479,29 +475,6 @@ this.CrashSubmit = {
     }
   },
 
-  /**
-   * Add a .dmg.ignore file along side the .dmp file to indicate that the user
-   * shouldn't be prompted to submit this crash report again.
-   *
-   * @param id
-   *        Filename (minus .dmp extension) of the report to ignore
-   */
-
-  ignore: function CrashSubmit_ignore(id) {
-    let [dump, extra, mem] = getPendingMinidump(id);
-    return new Promise(
-      function (resolve, reject) {
-        let promise = OS.File.open(dump.path + ".ignore", {create: true}, {unixFlags:OS.Constants.libc.O_CREAT});
-        promise.then(
-          function createSuccess(file) {
-            file.close();
-            resolve();
-          }
-        );
-      }
-    )
-  },
-
   /**
    * Get the list of pending crash IDs.
    *
@@ -512,64 +485,6 @@ this.CrashSubmit = {
     return getAllPendingMinidumpsIDs();
   },
 
-  /**
-   * Get the list of pending crash IDs, exluding those marked to be ignored
-   * @param maxFileDate
-   *     A Date object. Any files last modified before that date will be ignored
-   *
-   * @return a Promise that is fulfilled with an array of string, each
-   * being an ID as expected to be passed to submit() or ignore()
-   */
-  pendingIDsAsync: function CrashSubmit_pendingIDsAsync(maxFileDate) {
-    let promise = new Promise(function(resolve, reject) {
-      OS.File.stat(getDir("pending").path).then(
-        function onSuccess(info) {
-          if (info.isDir) {
-            let iterator = new OS.File.DirectoryIterator(getDir("pending").path);
-            let ids = [];
-            iterator.forEach(
-              function onEntry(file) {
-                if (file.name.endsWith(".dmp")) {
-                  return OS.File.exists(file.path + ".ignore").then(
-                    function onSuccess(ignoreExists) {
-                      if (!ignoreExists) {
-                        let id = file.name.slice(0, -4);
-                        if (UUID_REGEX.test(id)) {
-                          return OS.File.stat(file.path).then(
-                            function onSuccess(info) {
-                              if (info.lastAccessDate.valueOf() > maxFileDate.valueOf()) {
-                                ids.push(id);
-                              }
-                            }
-                          );
-                        }
-                      }
-                    }
-                  );
-                }
-              }
-            ).then(
-              function onSuccess() {
-                iterator.close();
-                resolve(ids);
-              },
-              function onError(err) {
-                iterator.close();
-                reject(err);
-              }
-            );
-          } else {
-            reject();
-          }
-        },
-        function onError(err) {
-          reject(err);
-        }
-      )
-    });
-    return promise;
-  },
-
   /**
    * Prune the saved dumps.
    */