From 0a9970498498aa966010f7b14e6c5b34a769de97 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Tue, 11 Jun 2019 17:03:41 +0100 Subject: [PATCH 01/14] Bug 1395509 - Track malloc memory used by native iterator objects r=jandem Use memory tracking APIs to track malloc memory associated with NativeIterator objects. I had to store the initial propery count as propertiesEnd can change during the lifetime of this object. Differential Revision: https://phabricator.services.mozilla.com/D34554 --- js/src/gc/GCEnum.h | 3 +- js/src/jit/BaselineCacheIRCompiler.cpp | 2 +- js/src/jit/IonCacheIRCompiler.cpp | 2 +- js/src/jit/MacroAssembler.cpp | 4 +-- js/src/vm/Iteration.cpp | 48 +++++++++++++++++++------- js/src/vm/Iteration.h | 47 +++++++++++++++++++------ 6 files changed, 77 insertions(+), 29 deletions(-) diff --git a/js/src/gc/GCEnum.h b/js/src/gc/GCEnum.h index 4703717d3fc26..6bdd4b07fbf99 100644 --- a/js/src/gc/GCEnum.h +++ b/js/src/gc/GCEnum.h @@ -112,7 +112,8 @@ enum class ZealMode { _(RegExpStatics) \ _(RegExpSharedBytecode) \ _(TypedArrayElements) \ - _(TypeDescrTraceList) + _(TypeDescrTraceList) \ + _(NativeIterator) #define JS_FOR_EACH_MEMORY_USE(_) \ JS_FOR_EACH_PUBLIC_MEMORY_USE(_) \ diff --git a/js/src/jit/BaselineCacheIRCompiler.cpp b/js/src/jit/BaselineCacheIRCompiler.cpp index 09b67a9b9308e..85c5394538b33 100644 --- a/js/src/jit/BaselineCacheIRCompiler.cpp +++ b/js/src/jit/BaselineCacheIRCompiler.cpp @@ -1831,7 +1831,7 @@ bool BaselineCacheIRCompiler::emitGuardAndGetIterator() { EmitPreBarrier(masm, iterObjAddr, MIRType::Object); // Mark iterator as active. - Address iterFlagsAddr(niScratch, NativeIterator::offsetOfFlags()); + Address iterFlagsAddr(niScratch, NativeIterator::offsetOfFlagsAndCount()); masm.storePtr(obj, iterObjAddr); masm.or32(Imm32(NativeIterator::Flags::Active), iterFlagsAddr); diff --git a/js/src/jit/IonCacheIRCompiler.cpp b/js/src/jit/IonCacheIRCompiler.cpp index 07fa7d604d0e9..0afa8a0226be6 100644 --- a/js/src/jit/IonCacheIRCompiler.cpp +++ b/js/src/jit/IonCacheIRCompiler.cpp @@ -2210,7 +2210,7 @@ bool IonCacheIRCompiler::emitGuardAndGetIterator() { EmitPreBarrier(masm, iterObjAddr, MIRType::Object); // Mark iterator as active. - Address iterFlagsAddr(niScratch, NativeIterator::offsetOfFlags()); + Address iterFlagsAddr(niScratch, NativeIterator::offsetOfFlagsAndCount()); masm.storePtr(obj, iterObjAddr); masm.or32(Imm32(NativeIterator::Flags::Active), iterFlagsAddr); diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index 13b92db3d9723..521509ac938f5 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -3462,7 +3462,7 @@ void MacroAssembler::debugAssertObjHasFixedSlots(Register obj, void MacroAssembler::branchIfNativeIteratorNotReusable(Register ni, Label* notReusable) { // See NativeIterator::isReusable. - Address flagsAddr(ni, NativeIterator::offsetOfFlags()); + Address flagsAddr(ni, NativeIterator::offsetOfFlagsAndCount()); #ifdef DEBUG Label niIsInitialized; @@ -3530,7 +3530,7 @@ void MacroAssembler::iteratorClose(Register obj, Register temp1, Register temp2, // Clear active bit. and32(Imm32(~NativeIterator::Flags::Active), - Address(temp1, NativeIterator::offsetOfFlags())); + Address(temp1, NativeIterator::offsetOfFlagsAndCount())); // Reset property cursor. loadPtr(Address(temp1, NativeIterator::offsetOfGuardsEnd()), temp2); diff --git a/js/src/vm/Iteration.cpp b/js/src/vm/Iteration.cpp index ce423aedbe75f..ae8e2e8fc3f49 100644 --- a/js/src/vm/Iteration.cpp +++ b/js/src/vm/Iteration.cpp @@ -592,14 +592,7 @@ static PropertyIteratorObject* NewPropertyIteratorObject(JSContext* cx) { return res; } -static PropertyIteratorObject* CreatePropertyIterator( - JSContext* cx, Handle objBeingIterated, HandleIdVector props, - uint32_t numGuards, uint32_t guardKey) { - Rooted propIter(cx, NewPropertyIteratorObject(cx)); - if (!propIter) { - return nullptr; - } - +static inline size_t ExtraStringCount(size_t propertyCount, size_t guardCount) { static_assert(sizeof(ReceiverGuard) == 2 * sizeof(GCPtrFlatString), "NativeIterators are allocated in space for 1) themselves, " "2) the properties a NativeIterator iterates (as " @@ -608,9 +601,24 @@ static PropertyIteratorObject* CreatePropertyIterator( "this size-relationship when determining the extra space to " "allocate"); - size_t extraCount = props.length() + numGuards * 2; - void* mem = - cx->pod_malloc_with_extra(extraCount); + return propertyCount + guardCount * 2; +} + +static inline size_t AllocationSize(size_t propertyCount, size_t guardCount) { + return sizeof(NativeIterator) + + ExtraStringCount(propertyCount, guardCount) * sizeof(GCPtrFlatString); +} + +static PropertyIteratorObject* CreatePropertyIterator( + JSContext* cx, Handle objBeingIterated, HandleIdVector props, + uint32_t numGuards, uint32_t guardKey) { + Rooted propIter(cx, NewPropertyIteratorObject(cx)); + if (!propIter) { + return nullptr; + } + + void* mem = cx->pod_malloc_with_extra( + ExtraStringCount(props.length(), numGuards)); if (!mem) { return nullptr; } @@ -680,7 +688,7 @@ NativeIterator::NativeIterator(JSContext* cx, reinterpret_cast(guardsBegin() + numGuards)), propertiesEnd_(propertyCursor_), guardKey_(guardKey), - flags_(0) // note: no Flags::Initialized + flagsAndCount_(0) // note: no Flags::Initialized { MOZ_ASSERT(!*hadError); @@ -688,6 +696,15 @@ NativeIterator::NativeIterator(JSContext* cx, // can only free |this| (and not leak it) if this has happened. propIter->setNativeIterator(this); + if (!setInitialPropertyCount(props.length())) { + ReportAllocationOverflow(cx); + *hadError = true; + return; + } + + size_t nbytes = AllocationSize(props.length(), numGuards); + AddCellMemory(propIter, nbytes, MemoryUse::NativeIterator); + for (size_t i = 0, len = props.length(); i < len; i++) { JSFlatString* str = IdToString(cx, props[i]); if (!str) { @@ -754,6 +771,11 @@ NativeIterator::NativeIterator(JSContext* cx, MOZ_ASSERT(!*hadError); } +inline size_t NativeIterator::allocationSize() const { + size_t numGuards = guardsEnd() - guardsBegin(); + return AllocationSize(initialPropertyCount(), numGuards); +} + /* static */ bool IteratorHashPolicy::match(PropertyIteratorObject* obj, const Lookup& lookup) { @@ -1059,7 +1081,7 @@ void PropertyIteratorObject::trace(JSTracer* trc, JSObject* obj) { void PropertyIteratorObject::finalize(FreeOp* fop, JSObject* obj) { if (NativeIterator* ni = obj->as().getNativeIterator()) { - fop->free_(ni); + fop->free_(obj, ni, ni->allocationSize(), MemoryUse::NativeIterator); } } diff --git a/js/src/vm/Iteration.h b/js/src/vm/Iteration.h index f7584517b8ea9..c24c6f076580e 100644 --- a/js/src/vm/Iteration.h +++ b/js/src/vm/Iteration.h @@ -87,7 +87,13 @@ struct NativeIterator { }; private: - uint32_t flags_ = 0; // consists of Flags bits + static constexpr uint32_t FlagsBits = 3; + static constexpr uint32_t FlagsMask = (1 << FlagsBits) - 1; + static constexpr uint32_t PropCountLimit = 1 << (32 - FlagsBits); + + // Stores Flags bits in the lower bits and the initial property count above + // them. + uint32_t flagsAndCount_ = 0; /* While in compartment->enumerators, these form a doubly linked list. */ NativeIterator* next_ = nullptr; @@ -223,31 +229,50 @@ struct NativeIterator { uint32_t guardKey() const { return guardKey_; } - bool isInitialized() const { return flags_ & Flags::Initialized; } + bool isInitialized() const { return flags() & Flags::Initialized; } + + size_t allocationSize() const; private: + uint32_t flags() const { return flagsAndCount_ & FlagsMask; } + + uint32_t initialPropertyCount() const { return flagsAndCount_ >> FlagsBits; } + + void setFlags(uint32_t flags) { + MOZ_ASSERT((flags & ~FlagsMask) == 0); + flagsAndCount_ = (initialPropertyCount() << FlagsBits) | flags; + } + + MOZ_MUST_USE bool setInitialPropertyCount(uint32_t count) { + if (count >= PropCountLimit) { + return false; + } + flagsAndCount_ = (count << FlagsBits) | flags(); + return true; + } + void markInitialized() { - MOZ_ASSERT(flags_ == 0); - flags_ = Flags::Initialized; + MOZ_ASSERT(flags() == 0); + setFlags(Flags::Initialized); } public: bool isActive() const { MOZ_ASSERT(isInitialized()); - return flags_ & Flags::Active; + return flags() & Flags::Active; } void markActive() { MOZ_ASSERT(isInitialized()); - flags_ |= Flags::Active; + flagsAndCount_ |= Flags::Active; } void markInactive() { MOZ_ASSERT(isInitialized()); - flags_ &= ~Flags::Active; + flagsAndCount_ &= ~Flags::Active; } bool isReusable() const { @@ -258,13 +283,13 @@ struct NativeIterator { // |Flags::Initialized| is set. Using |Flags::NotReusable| to test // would also work, but this formulation is safer against memory // corruption. - return flags_ == Flags::Initialized; + return flags() == Flags::Initialized; } void markHasUnvisitedPropertyDeletion() { MOZ_ASSERT(isInitialized()); - flags_ |= Flags::HasUnvisitedPropertyDeletion; + flagsAndCount_ |= Flags::HasUnvisitedPropertyDeletion; } void link(NativeIterator* other) { @@ -310,8 +335,8 @@ struct NativeIterator { return offsetof(NativeIterator, propertiesEnd_); } - static constexpr size_t offsetOfFlags() { - return offsetof(NativeIterator, flags_); + static constexpr size_t offsetOfFlagsAndCount() { + return offsetof(NativeIterator, flagsAndCount_); } static constexpr size_t offsetOfNext() { From f341cb1dd787d5a10c4dd4392f85088f3dccece0 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Tue, 18 Jun 2019 13:33:43 -0700 Subject: [PATCH 02/14] Bug 1395509 - Track malloc memory used by JitScripts r=jandem Differential Revision: https://phabricator.services.mozilla.com/D35345 --- js/src/gc/GCEnum.h | 3 ++- js/src/jit/Ion.cpp | 2 +- js/src/jit/JitScript.cpp | 16 ++++++++++++---- js/src/jit/JitScript.h | 7 ++++++- js/src/vm/Iteration.cpp | 2 +- js/src/vm/JSScript.h | 1 + 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/js/src/gc/GCEnum.h b/js/src/gc/GCEnum.h index 6bdd4b07fbf99..99d0976e64e57 100644 --- a/js/src/gc/GCEnum.h +++ b/js/src/gc/GCEnum.h @@ -113,7 +113,8 @@ enum class ZealMode { _(RegExpSharedBytecode) \ _(TypedArrayElements) \ _(TypeDescrTraceList) \ - _(NativeIterator) + _(NativeIterator) \ + _(JitScript) #define JS_FOR_EACH_MEMORY_USE(_) \ JS_FOR_EACH_PUBLIC_MEMORY_USE(_) \ diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 392fa619ed5c5..0da32e593f8e4 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -3145,7 +3145,7 @@ void jit::DestroyJitScripts(FreeOp* fop, JSScript* script) { } if (script->hasJitScript()) { - JitScript::Destroy(script->zone(), script->jitScript()); + script->releaseJitScript(); } } diff --git a/js/src/jit/JitScript.cpp b/js/src/jit/JitScript.cpp index 2f9096db44907..dcf56291dc34a 100644 --- a/js/src/jit/JitScript.cpp +++ b/js/src/jit/JitScript.cpp @@ -40,9 +40,10 @@ static size_t NumTypeSets(JSScript* script) { } JitScript::JitScript(JSScript* script, uint32_t typeSetOffset, - uint32_t bytecodeTypeMapOffset) + uint32_t bytecodeTypeMapOffset, uint32_t allocBytes) : typeSetOffset_(typeSetOffset), - bytecodeTypeMapOffset_(bytecodeTypeMapOffset) { + bytecodeTypeMapOffset_(bytecodeTypeMapOffset), + allocBytes_(allocBytes) { setTypesGeneration(script->zone()->types.generation); uint8_t* base = reinterpret_cast(this); @@ -98,8 +99,8 @@ bool JSScript::createJitScript(JSContext* cx) { uint32_t typeSetOffset = sizeof(JitScript) + numICEntries() * sizeof(ICEntry); uint32_t bytecodeTypeMapOffset = typeSetOffset + numTypeSets * sizeof(StackTypeSet); - UniquePtr jitScript( - new (raw) JitScript(this, typeSetOffset, bytecodeTypeMapOffset)); + UniquePtr jitScript(new (raw) JitScript( + this, typeSetOffset, bytecodeTypeMapOffset, allocSize.value())); // Sanity check the length computations. MOZ_ASSERT(jitScript->numICEntries() == numICEntries()); @@ -116,6 +117,7 @@ bool JSScript::createJitScript(JSContext* cx) { MOZ_ASSERT(!jitScript_); prepareForDestruction.release(); jitScript_ = jitScript.release(); + AddCellMemory(this, allocSize.value(), MemoryUse::JitScript); // We have a JitScript so we can set the script's jitCodeRaw_ pointer to the // Baseline Interpreter code. @@ -150,8 +152,14 @@ void JSScript::maybeReleaseJitScript() { return; } + releaseJitScript(); +} + +void JSScript::releaseJitScript() { MOZ_ASSERT(!hasIonScript()); + RemoveCellMemory(this, jitScript_->allocBytes(), MemoryUse::JitScript); + JitScript::Destroy(zone(), jitScript_); jitScript_ = nullptr; updateJitCodeRaw(runtimeFromMainThread()); diff --git a/js/src/jit/JitScript.h b/js/src/jit/JitScript.h index cefebd0f28c20..63772182f225f 100644 --- a/js/src/jit/JitScript.h +++ b/js/src/jit/JitScript.h @@ -115,6 +115,9 @@ class alignas(uintptr_t) JitScript final { // bytecode map queries are in linear order. uint32_t bytecodeTypeMapHint_ = 0; + // The size of this allocation. + uint32_t allocBytes_ = 0; + struct Flags { // Flag set when discarding JIT code to indicate this script is on the stack // and type information and JIT code should not be discarded. @@ -147,7 +150,7 @@ class alignas(uintptr_t) JitScript final { public: JitScript(JSScript* script, uint32_t typeSetOffset, - uint32_t bytecodeTypeMapOffset); + uint32_t bytecodeTypeMapOffset, uint32_t allocBytes); #ifdef DEBUG ~JitScript() { @@ -327,6 +330,8 @@ class alignas(uintptr_t) JitScript final { uint32_t idx); void removeDependentWasmImport(wasm::Instance& instance, uint32_t idx); void unlinkDependentWasmImports(); + + size_t allocBytes() const { return allocBytes_; } }; // Ensures no JitScripts are purged in the current zone. diff --git a/js/src/vm/Iteration.cpp b/js/src/vm/Iteration.cpp index ae8e2e8fc3f49..91a39a4b06295 100644 --- a/js/src/vm/Iteration.cpp +++ b/js/src/vm/Iteration.cpp @@ -606,7 +606,7 @@ static inline size_t ExtraStringCount(size_t propertyCount, size_t guardCount) { static inline size_t AllocationSize(size_t propertyCount, size_t guardCount) { return sizeof(NativeIterator) + - ExtraStringCount(propertyCount, guardCount) * sizeof(GCPtrFlatString); + ExtraStringCount(propertyCount, guardCount) * sizeof(GCPtrFlatString); } static PropertyIteratorObject* CreatePropertyIterator( diff --git a/js/src/vm/JSScript.h b/js/src/vm/JSScript.h index 94bbae140a910..f4eef6c4d55b2 100644 --- a/js/src/vm/JSScript.h +++ b/js/src/vm/JSScript.h @@ -2661,6 +2661,7 @@ class JSScript : public js::gc::TenuredCell { js::jit::JitScript* jitScript() { return jitScript_; } void maybeReleaseJitScript(); + void releaseJitScript(); inline js::GlobalObject& global() const; inline bool hasGlobal(const js::GlobalObject* global) const; From a1e98968b9fd823e1d9923b0b2b9119db05eab28 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 19 Jun 2019 11:14:11 -0700 Subject: [PATCH 03/14] Bug 1395509 - Track malloc memory used by ObjectGroups r=tcampbell Differential Revision: https://phabricator.services.mozilla.com/D35346 --- js/src/gc/GCEnum.h | 3 +- js/src/vm/ObjectGroup.cpp | 29 ++++++++++++++--- js/src/vm/TypeInference-inl.h | 12 ++++++- js/src/vm/TypeInference.cpp | 59 +++++++++++++++++++++++++---------- 4 files changed, 80 insertions(+), 23 deletions(-) diff --git a/js/src/gc/GCEnum.h b/js/src/gc/GCEnum.h index 99d0976e64e57..58acf548fdf89 100644 --- a/js/src/gc/GCEnum.h +++ b/js/src/gc/GCEnum.h @@ -114,7 +114,8 @@ enum class ZealMode { _(TypedArrayElements) \ _(TypeDescrTraceList) \ _(NativeIterator) \ - _(JitScript) + _(JitScript) \ + _(ObjectGroupAddendum) #define JS_FOR_EACH_MEMORY_USE(_) \ JS_FOR_EACH_PUBLIC_MEMORY_USE(_) \ diff --git a/js/src/vm/ObjectGroup.cpp b/js/src/vm/ObjectGroup.cpp index b66693cb12da2..bebdf828dee7b 100644 --- a/js/src/vm/ObjectGroup.cpp +++ b/js/src/vm/ObjectGroup.cpp @@ -48,14 +48,16 @@ ObjectGroup::ObjectGroup(const Class* clasp, TaggedProto proto, } void ObjectGroup::finalize(FreeOp* fop) { - if (newScriptDontCheckGeneration()) { - newScriptDontCheckGeneration()->clear(); + if (auto newScript = newScriptDontCheckGeneration()) { + newScript->clear(); + fop->delete_(this, newScript, newScript->gcMallocBytes(), + MemoryUse::ObjectGroupAddendum); } - fop->delete_(newScriptDontCheckGeneration()); if (maybePreliminaryObjectsDontCheckGeneration()) { maybePreliminaryObjectsDontCheckGeneration()->clear(); } - fop->delete_(maybePreliminaryObjectsDontCheckGeneration()); + fop->delete_(this, maybePreliminaryObjectsDontCheckGeneration(), + MemoryUse::ObjectGroupAddendum); } void ObjectGroup::setProtoUnchecked(TaggedProto proto) { @@ -78,11 +80,27 @@ size_t ObjectGroup::sizeOfExcludingThis( return n; } +static inline size_t AddendumAllocSize(ObjectGroup::AddendumKind kind, + void* addendum) { + if (kind == ObjectGroup::Addendum_NewScript) { + auto newScript = static_cast(addendum); + return newScript->gcMallocBytes(); + } + if (kind == ObjectGroup::Addendum_PreliminaryObjects) { + return sizeof(PreliminaryObjectArrayWithTemplate); + } + // Other addendum kinds point to GC memory tracked elsewhere. + return 0; +} + void ObjectGroup::setAddendum(AddendumKind kind, void* addendum, bool writeBarrier /* = true */) { MOZ_ASSERT(!needsSweep()); MOZ_ASSERT(kind <= (OBJECT_FLAG_ADDENDUM_MASK >> OBJECT_FLAG_ADDENDUM_SHIFT)); + RemoveCellMemory(this, AddendumAllocSize(addendumKind(), addendum_), + MemoryUse::ObjectGroupAddendum); + if (writeBarrier) { // Manually trigger barriers if we are clearing new script or // preliminary object information. Other addendums are immutable. @@ -105,6 +123,9 @@ void ObjectGroup::setAddendum(AddendumKind kind, void* addendum, flags_ &= ~OBJECT_FLAG_ADDENDUM_MASK; flags_ |= kind << OBJECT_FLAG_ADDENDUM_SHIFT; addendum_ = addendum; + + AddCellMemory(this, AddendumAllocSize(kind, addendum), + MemoryUse::ObjectGroupAddendum); } /* static */ diff --git a/js/src/vm/TypeInference-inl.h b/js/src/vm/TypeInference-inl.h index 9bcb1f1d7922c..8e4b02d9b6e30 100644 --- a/js/src/vm/TypeInference-inl.h +++ b/js/src/vm/TypeInference-inl.h @@ -282,6 +282,12 @@ static inline const char* TypeIdString(jsid id) { // complex ways which can't be understood statically. class TypeNewScript { private: + // Variable-length list of TypeNewScriptInitializer pointers. + struct InitializerList { + size_t length; + TypeNewScriptInitializer entries[1]; + }; + // Scripted function which this information was computed for. HeapPtr function_ = {}; @@ -303,7 +309,7 @@ class TypeNewScript { // shape. Property assignments in inner frames are preceded by a series of // SETPROP_FRAME entries specifying the stack down to the frame containing // the write. - TypeNewScriptInitializer* initializerList = nullptr; + InitializerList* initializerList = nullptr; // If there are additional properties found by the acquired properties // analysis which were not found by the definite properties analysis, this @@ -356,9 +362,13 @@ class TypeNewScript { size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + size_t gcMallocBytes() const; + static size_t offsetOfPreliminaryObjects() { return offsetof(TypeNewScript, preliminaryObjects); } + + static size_t sizeOfInitializerList(size_t length); }; inline bool ObjectGroup::hasUnanalyzedPreliminaryObjects() { diff --git a/js/src/vm/TypeInference.cpp b/js/src/vm/TypeInference.cpp index ac098288546e9..526e7758040a9 100644 --- a/js/src/vm/TypeInference.cpp +++ b/js/src/vm/TypeInference.cpp @@ -3679,6 +3679,26 @@ size_t TypeNewScript::sizeOfIncludingThis( return n; } +/* static */ size_t TypeNewScript::sizeOfInitializerList(size_t length) { + // TypeNewScriptInitializer struct contains [1] element in its size. + size_t size = sizeof(TypeNewScript::InitializerList); + if (length > 0) { + size += (length - 1) * sizeof(TypeNewScriptInitializer); + } + return size; +} + +size_t TypeNewScript::gcMallocBytes() const { + size_t size = sizeof(TypeNewScript); + if (preliminaryObjects) { + size += sizeof(PreliminaryObjectArray); + } + if (initializerList) { + size += sizeOfInitializerList(initializerList->length); + } + return size; +} + void TypeNewScript::registerNewObject(PlainObject* res) { MOZ_ASSERT(!analyzed()); @@ -3835,6 +3855,8 @@ bool TypeNewScript::maybeAnalyze(JSContext* cx, ObjectGroup* group, MOZ_ASSERT(OnlyHasDataProperties(templateObject()->lastProperty())); + MOZ_ASSERT(!initializerList); + InitializerList* newInitializerList = nullptr; if (templateObject()->slotSpan() != 0) { // Make sure that all definite properties found are reflected in the // prefix shape. Otherwise, the constructor behaved differently before @@ -3866,25 +3888,27 @@ bool TypeNewScript::maybeAnalyze(JSContext* cx, ObjectGroup* group, } } - TypeNewScriptInitializer done(TypeNewScriptInitializer::DONE, 0); - - if (!initializerVector.append(done)) { - return false; - } - - initializerList = group->zone()->pod_calloc( - initializerVector.length()); - if (!initializerList) { + size_t nbytes = sizeOfInitializerList(initializerVector.length()); + newInitializerList = reinterpret_cast( + group->zone()->pod_calloc(nbytes)); + if (!newInitializerList) { ReportOutOfMemory(cx); return false; } - PodCopy(initializerList, initializerVector.begin(), + newInitializerList->length = initializerVector.length(); + PodCopy(newInitializerList->entries, initializerVector.begin(), initializerVector.length()); } + RemoveCellMemory(group, gcMallocBytes(), MemoryUse::ObjectGroupAddendum); + + initializerList = newInitializerList; + js_delete(preliminaryObjects); preliminaryObjects = nullptr; + AddCellMemory(group, gcMallocBytes(), MemoryUse::ObjectGroupAddendum); + if (prefixShape->slotSpan() == templateObject()->slotSpan()) { // The definite properties analysis found exactly the properties that // are held in common by the preliminary objects. No further analysis @@ -4006,9 +4030,10 @@ bool TypeNewScript::rollbackPartiallyInitializedObjects(JSContext* cx, // Index in pcOffsets of the frame currently being checked for a SETPROP. int setpropDepth = callDepth; - for (TypeNewScriptInitializer* init = initializerList;; init++) { - if (init->kind == TypeNewScriptInitializer::SETPROP) { - if (!pastProperty && pcOffsets[setpropDepth] < init->offset) { + for (size_t i = 0; i < initializerList->length; i++) { + const TypeNewScriptInitializer init = initializerList->entries[i]; + if (init.kind == TypeNewScriptInitializer::SETPROP) { + if (!pastProperty && pcOffsets[setpropDepth] < init.offset) { // Have not yet reached this setprop. break; } @@ -4016,12 +4041,12 @@ bool TypeNewScript::rollbackPartiallyInitializedObjects(JSContext* cx, numProperties++; pastProperty = false; setpropDepth = callDepth; - } else if (init->kind == TypeNewScriptInitializer::SETPROP_FRAME) { + } else if (init.kind == TypeNewScriptInitializer::SETPROP_FRAME) { if (!pastProperty) { - if (pcOffsets[setpropDepth] < init->offset) { + if (pcOffsets[setpropDepth] < init.offset) { // Have not yet reached this inner call. break; - } else if (pcOffsets[setpropDepth] > init->offset) { + } else if (pcOffsets[setpropDepth] > init.offset) { // Have advanced past this inner call. pastProperty = true; } else if (setpropDepth == 0) { @@ -4033,7 +4058,7 @@ bool TypeNewScript::rollbackPartiallyInitializedObjects(JSContext* cx, } } } else { - MOZ_ASSERT(init->kind == TypeNewScriptInitializer::DONE); + MOZ_ASSERT(init.kind == TypeNewScriptInitializer::DONE); finished = true; break; } From f28f3976aa8fa3cb657232df0eaed22238e1e033 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 19 Jun 2019 11:15:40 -0700 Subject: [PATCH 04/14] Bug 1395509 - Track malloc memory used by script breakpoints r=sfink Differential Revision: https://phabricator.services.mozilla.com/D35347 --- js/src/gc/GCEnum.h | 4 +++- js/src/gc/Zone.cpp | 3 ++- js/src/vm/JSScript.cpp | 27 ++++++++++++++++----------- js/src/vm/JSScript.h | 6 ++++++ 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/js/src/gc/GCEnum.h b/js/src/gc/GCEnum.h index 58acf548fdf89..ff28a74180a07 100644 --- a/js/src/gc/GCEnum.h +++ b/js/src/gc/GCEnum.h @@ -115,7 +115,9 @@ enum class ZealMode { _(TypeDescrTraceList) \ _(NativeIterator) \ _(JitScript) \ - _(ObjectGroupAddendum) + _(ObjectGroupAddendum) \ + _(ScriptDebugScript) \ + _(BreakpointSite) #define JS_FOR_EACH_MEMORY_USE(_) \ JS_FOR_EACH_PUBLIC_MEMORY_USE(_) \ diff --git a/js/src/gc/Zone.cpp b/js/src/gc/Zone.cpp index f8f191b552387..31ab555dad5d7 100644 --- a/js/src/gc/Zone.cpp +++ b/js/src/gc/Zone.cpp @@ -701,7 +701,8 @@ void MemoryTracker::checkEmptyOnDestroy() { inline bool MemoryTracker::allowMultipleAssociations(MemoryUse use) const { // For most uses only one association is possible for each GC thing. Allow a // one-to-many relationship only where necessary. - return use == MemoryUse::RegExpSharedBytecode; + return use == MemoryUse::RegExpSharedBytecode || + use == MemoryUse::BreakpointSite; } void MemoryTracker::trackMemory(Cell* cell, size_t nbytes, MemoryUse use) { diff --git a/js/src/vm/JSScript.cpp b/js/src/vm/JSScript.cpp index a08eb280d1729..2943f86ab89ce 100644 --- a/js/src/vm/JSScript.cpp +++ b/js/src/vm/JSScript.cpp @@ -4657,24 +4657,25 @@ void JSScript::destroyDebugScript(FreeOp* fop) { if (hasDebugScript()) { #ifdef DEBUG for (jsbytecode* pc = code(); pc < codeEnd(); pc++) { - if (BreakpointSite* site = getBreakpointSite(pc)) { - /* Breakpoints are swept before finalization. */ - MOZ_ASSERT(site->firstBreakpoint() == nullptr); - MOZ_ASSERT(getBreakpointSite(pc) == nullptr); - } + MOZ_ASSERT(!getBreakpointSite(pc)); } #endif - fop->free_(releaseDebugScript()); + freeDebugScript(fop); } } +void JSScript::freeDebugScript(FreeOp* fop) { + MOZ_ASSERT(hasDebugScript()); + fop->free_(this, releaseDebugScript(), DebugScript::allocSize(length()), + MemoryUse::ScriptDebugScript); +} + DebugScript* JSScript::getOrCreateDebugScript(JSContext* cx) { if (hasDebugScript()) { return debugScript(); } - size_t nbytes = - offsetof(DebugScript, breakpoints) + length() * sizeof(BreakpointSite*); + size_t nbytes = DebugScript::allocSize(length()); UniqueDebugScript debug( reinterpret_cast(cx->pod_calloc(nbytes))); if (!debug) { @@ -4699,6 +4700,7 @@ DebugScript* JSScript::getOrCreateDebugScript(JSContext* cx) { setFlag(MutableFlags::HasDebugScript); // safe to set this; we can't fail // after this point + AddCellMemory(this, nbytes, MemoryUse::ScriptDebugScript); /* * Ensure that any Interpret() instances running on this script have @@ -4744,7 +4746,7 @@ void JSScript::decrementGeneratorObserverCount(js::FreeOp* fop) { debug->generatorObserverCount--; if (!debug->needed()) { - fop->free_(releaseDebugScript()); + destroyDebugScript(fop); } } @@ -4783,7 +4785,7 @@ void JSScript::decrementStepperCount(FreeOp* fop) { } if (!debug->needed()) { - fop->free_(releaseDebugScript()); + freeDebugScript(fop); } } } @@ -4805,6 +4807,7 @@ BreakpointSite* JSScript::getOrCreateBreakpointSite(JSContext* cx, return nullptr; } debug->numSites++; + AddCellMemory(this, sizeof(JSBreakpointSite), MemoryUse::BreakpointSite); } return site; @@ -4815,12 +4818,14 @@ void JSScript::destroyBreakpointSite(FreeOp* fop, jsbytecode* pc) { BreakpointSite*& site = debug->breakpoints[pcToOffset(pc)]; MOZ_ASSERT(site); + RemoveCellMemory(this, sizeof(JSBreakpointSite), MemoryUse::BreakpointSite); + fop->delete_(site); site = nullptr; debug->numSites--; if (!debug->needed()) { - fop->free_(releaseDebugScript()); + freeDebugScript(fop); } } diff --git a/js/src/vm/JSScript.h b/js/src/vm/JSScript.h index f4eef6c4d55b2..9e5fbbefb5145 100644 --- a/js/src/vm/JSScript.h +++ b/js/src/vm/JSScript.h @@ -298,6 +298,11 @@ class DebugScript { bool needed() const { return generatorObserverCount > 0 || stepperCount > 0 || numSites > 0; } + + static size_t allocSize(size_t codeLength) { + return offsetof(DebugScript, breakpoints) + + codeLength * sizeof(BreakpointSite*); + } }; using UniqueDebugScript = js::UniquePtr; @@ -2959,6 +2964,7 @@ class JSScript : public js::gc::TenuredCell { js::DebugScript* debugScript(); js::DebugScript* releaseDebugScript(); void destroyDebugScript(js::FreeOp* fop); + void freeDebugScript(js::FreeOp* fop); bool hasDebugScript() const { return hasFlag(MutableFlags::HasDebugScript); } From 55989a8748797d1980ed818c25126232faa81f8a Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 19 Jun 2019 11:34:36 -0700 Subject: [PATCH 05/14] Bug 1395509 - Track malloc memory used by ForOfPIC objects r=jandem This refactors freeing stubs and adds memory tracking. It also adds a back pointer to the JSObject to ForOfPIC::Chain which is slightly annoying, but I think there's only one per global so this shouldn't be too bad. Differential Revision: https://phabricator.services.mozilla.com/D35348 --- js/src/gc/GCEnum.h | 4 ++- js/src/gc/Zone.cpp | 2 +- js/src/vm/PIC.cpp | 81 ++++++++++++++++++++++++++++------------------ js/src/vm/PIC.h | 40 +++++++---------------- 4 files changed, 65 insertions(+), 62 deletions(-) diff --git a/js/src/gc/GCEnum.h b/js/src/gc/GCEnum.h index ff28a74180a07..bc7455e5604b0 100644 --- a/js/src/gc/GCEnum.h +++ b/js/src/gc/GCEnum.h @@ -117,7 +117,9 @@ enum class ZealMode { _(JitScript) \ _(ObjectGroupAddendum) \ _(ScriptDebugScript) \ - _(BreakpointSite) + _(BreakpointSite) \ + _(ForOfPIC) \ + _(ForOfPICStub) #define JS_FOR_EACH_MEMORY_USE(_) \ JS_FOR_EACH_PUBLIC_MEMORY_USE(_) \ diff --git a/js/src/gc/Zone.cpp b/js/src/gc/Zone.cpp index 31ab555dad5d7..a5c071f44280d 100644 --- a/js/src/gc/Zone.cpp +++ b/js/src/gc/Zone.cpp @@ -702,7 +702,7 @@ inline bool MemoryTracker::allowMultipleAssociations(MemoryUse use) const { // For most uses only one association is possible for each GC thing. Allow a // one-to-many relationship only where necessary. return use == MemoryUse::RegExpSharedBytecode || - use == MemoryUse::BreakpointSite; + use == MemoryUse::BreakpointSite || use == MemoryUse::ForOfPICStub; } void MemoryTracker::trackMemory(Cell* cell, size_t nbytes, MemoryUse use) { diff --git a/js/src/vm/PIC.cpp b/js/src/vm/PIC.cpp index 8186e81ab7694..ebc0f18e3ee54 100644 --- a/js/src/vm/PIC.cpp +++ b/js/src/vm/PIC.cpp @@ -19,6 +19,25 @@ using namespace js; +template +void PICChain::addStub(JSObject* obj, CatStub* stub) { + MOZ_ASSERT(stub); + MOZ_ASSERT(!stub->next()); + + AddCellMemory(obj, sizeof(CatStub), MemoryUse::ForOfPICStub); + + if (!stubs_) { + stubs_ = stub; + return; + } + + CatStub* cur = stubs_; + while (cur->next()) { + cur = cur->next(); + } + cur->append(stub); +} + bool js::ForOfPIC::Chain::initialize(JSContext* cx) { MOZ_ASSERT(!initialized_); @@ -106,7 +125,7 @@ bool js::ForOfPIC::Chain::tryOptimizeArray(JSContext* cx, } else if (!disabled_ && !isArrayStateStillSane()) { // Otherwise, if array state is no longer sane, reinitialize. - reset(); + reset(cx); if (!initialize(cx)) { return false; @@ -142,7 +161,7 @@ bool js::ForOfPIC::Chain::tryOptimizeArray(JSContext* cx, // existing cache before adding new stubs. We shouldn't really have heavy // churn on these. if (numStubs() >= MAX_STUBS) { - eraseChain(); + eraseChain(cx); } // Good to optimize now, create stub to add. @@ -153,7 +172,7 @@ bool js::ForOfPIC::Chain::tryOptimizeArray(JSContext* cx, } // Add the stub. - addStub(stub); + addStub(picObject_, stub); *optimized = true; return true; @@ -172,7 +191,7 @@ bool js::ForOfPIC::Chain::tryOptimizeArrayIteratorNext(JSContext* cx, } } else if (!disabled_ && !isArrayNextStillSane()) { // Otherwise, if array iterator state is no longer sane, reinitialize. - reset(); + reset(cx); if (!initialize(cx)) { return false; @@ -222,12 +241,12 @@ bool js::ForOfPIC::Chain::isArrayStateStillSane() { return isArrayNextStillSane(); } -void js::ForOfPIC::Chain::reset() { +void js::ForOfPIC::Chain::reset(JSContext* cx) { // Should never reset a disabled_ stub. MOZ_ASSERT(!disabled_); // Erase the chain. - eraseChain(); + eraseChain(cx); arrayProto_ = nullptr; arrayIteratorProto_ = nullptr; @@ -243,22 +262,16 @@ void js::ForOfPIC::Chain::reset() { initialized_ = false; } -void js::ForOfPIC::Chain::eraseChain() { +void js::ForOfPIC::Chain::eraseChain(JSContext* cx) { // Should never need to clear the chain of a disabled stub. MOZ_ASSERT(!disabled_); - - // Free all stubs. - Stub* stub = stubs_; - while (stub) { - Stub* next = stub->next(); - js_delete(stub); - stub = next; - } - stubs_ = nullptr; + freeAllStubs(cx->defaultFreeOp()); } // Trace the pointers stored directly on the stub. void js::ForOfPIC::Chain::trace(JSTracer* trc) { + TraceEdge(trc, &picObject_, "ForOfPIC object"); + if (!initialized_ || disabled_) { return; } @@ -274,28 +287,33 @@ void js::ForOfPIC::Chain::trace(JSTracer* trc) { TraceEdge(trc, &canonicalNextFunc_, "ForOfPIC ArrayIterator.prototype.next builtin."); - // Free all the stubs in the chain. - while (stubs_) { - removeStub(stubs_, nullptr); - } -} - -void js::ForOfPIC::Chain::sweep(FreeOp* fop) { - // Free all the stubs in the chain. - while (stubs_) { - Stub* next = stubs_->next(); - fop->delete_(stubs_); - stubs_ = next; + if (trc->isMarkingTracer()) { + // Free all the stubs in the chain. + freeAllStubs(trc->runtime()->defaultFreeOp()); } - fop->delete_(this); } static void ForOfPIC_finalize(FreeOp* fop, JSObject* obj) { MOZ_ASSERT(fop->maybeOnHelperThread()); if (ForOfPIC::Chain* chain = ForOfPIC::fromJSObject(&obj->as())) { - chain->sweep(fop); + chain->finalize(fop, obj); + } +} + +void js::ForOfPIC::Chain::finalize(FreeOp* fop, JSObject* obj) { + freeAllStubs(fop); + fop->delete_(obj, this, MemoryUse::ForOfPIC); +} + +void js::ForOfPIC::Chain::freeAllStubs(FreeOp* fop) { + Stub* stub = stubs_; + while (stub) { + Stub* next = stub->next(); + fop->delete_(picObject_, stub, MemoryUse::ForOfPICStub); + stub = next; } + stubs_ = nullptr; } static void ForOfPIC_traceObject(JSTracer* trc, JSObject* obj) { @@ -330,10 +348,11 @@ NativeObject* js::ForOfPIC::createForOfPICObject(JSContext* cx, if (!obj) { return nullptr; } - ForOfPIC::Chain* chain = cx->new_(); + ForOfPIC::Chain* chain = cx->new_(obj); if (!chain) { return nullptr; } + InitObjectPrivate(obj, chain, MemoryUse::ForOfPIC); obj->setPrivate(chain); return obj; } diff --git a/js/src/vm/PIC.h b/js/src/vm/PIC.h index 667336d621c1c..e28e146d215a6 100644 --- a/js/src/vm/PIC.h +++ b/js/src/vm/PIC.h @@ -64,20 +64,7 @@ class PICChain { public: CatStub* stubs() const { return stubs_; } - void addStub(CatStub* stub) { - MOZ_ASSERT(stub); - MOZ_ASSERT(!stub->next()); - if (!stubs_) { - stubs_ = stub; - return; - } - - CatStub* cur = stubs_; - while (cur->next()) { - cur = cur->next(); - } - cur->append(stub); - } + void addStub(JSObject* obj, CatStub* stub); unsigned numStubs() const { unsigned count = 0; @@ -86,17 +73,6 @@ class PICChain { } return count; } - - void removeStub(CatStub* stub, CatStub* previous) { - if (previous) { - MOZ_ASSERT(previous->next() == stub); - previous->next_ = stub->next(); - } else { - MOZ_ASSERT(stub == stubs_); - stubs_ = stub->next(); - } - js_delete(stub); - } }; /* @@ -158,6 +134,9 @@ struct ForOfPIC { */ class Chain : public BaseChain { private: + // Pointer to owning JSObject for memory accounting purposes. + GCPtrObject picObject_; + // Pointer to canonical Array.prototype and ArrayIterator.prototype GCPtrNativeObject arrayProto_; GCPtrNativeObject arrayIteratorProto_; @@ -184,8 +163,9 @@ struct ForOfPIC { static const unsigned MAX_STUBS = 10; public: - Chain() + explicit Chain(JSObject* picObject) : BaseChain(), + picObject_(picObject), arrayProto_(nullptr), arrayIteratorProto_(nullptr), arrayProtoShape_(nullptr), @@ -207,7 +187,7 @@ struct ForOfPIC { bool tryOptimizeArrayIteratorNext(JSContext* cx, bool* optimized); void trace(JSTracer* trc); - void sweep(FreeOp* fop); + void finalize(FreeOp* fop, JSObject* obj); private: // Check if the global array-related objects have not been messed with @@ -226,10 +206,12 @@ struct ForOfPIC { bool hasMatchingStub(ArrayObject* obj); // Reset the PIC and all info associated with it. - void reset(); + void reset(JSContext* cx); // Erase the stub chain. - void eraseChain(); + void eraseChain(JSContext* cx); + + void freeAllStubs(FreeOp* fop); }; // Class for object that holds ForOfPIC chain. From 969e1e3eba5714ba5d7602ba8e9e51db7f8594b5 Mon Sep 17 00:00:00 2001 From: "arthur.iakab" Date: Fri, 21 Jun 2019 00:26:39 +0300 Subject: [PATCH 06/14] Bug 1560360 - Disabled css-appearance-push-button-001 on win7 debug a=testonly --- .../meta/css/css-ui/appearance-push-button-001.html.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testing/web-platform/meta/css/css-ui/appearance-push-button-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-push-button-001.html.ini index 4409dd0dfe6e4..b2d4d56dfa8b0 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-push-button-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-push-button-001.html.ini @@ -1,3 +1,5 @@ [appearance-push-button-001.html] + disabled: + if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if os == "win": FAIL From f470b0aee37490aff3c49d9df6973399387e5a58 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Mon, 17 Jun 2019 15:03:03 +0200 Subject: [PATCH 07/14] Bug 1558705 - [css-grid-2] Account for the subgrid's margin/border/padding when resolving its non-subgridded track sizes. r=dholbert Differential Revision: https://phabricator.services.mozilla.com/D35192 --- layout/generic/nsGridContainerFrame.cpp | 37 +++++----- .../subgrid/auto-track-sizing-001-ref.html | 65 ++++++++++++++++++ .../subgrid/auto-track-sizing-001.html | 68 +++++++++++++++++++ 3 files changed, 153 insertions(+), 17 deletions(-) create mode 100644 testing/web-platform/tests/css/css-grid/subgrid/auto-track-sizing-001-ref.html create mode 100644 testing/web-platform/tests/css/css-grid/subgrid/auto-track-sizing-001.html diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 402f4d65166c4..a9cab8dc58773 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -808,7 +808,7 @@ struct nsGridContainerFrame::UsedTrackSizes { /** Helper function for the above method */ void ResolveSubgridTrackSizesForAxis(nsGridContainerFrame* aFrame, LogicalAxis aAxis, Subgrid* aSubgrid, - gfxContext& aRC, nscoord aCBSize); + gfxContext& aRC, nscoord aContentBoxSize); // This only has valid sizes when mCanResolveLineRangeSize is true in // the same axis. It may have zero tracks (a grid with only abs.pos. @@ -2021,7 +2021,7 @@ struct nsGridContainerFrame::Tracks { void CalculateSizes(GridReflowInput& aState, nsTArray& aGridItems, const TrackSizingFunctions& aFunctions, - nscoord aContentSize, LineRange GridArea::*aRange, + nscoord aContentBoxSize, LineRange GridArea::*aRange, SizingConstraint aConstraint); /** @@ -2029,7 +2029,7 @@ struct nsGridContainerFrame::Tracks { * https://drafts.csswg.org/css-align-3/#propdef-align-content */ void AlignJustifyContent(const nsStylePosition* aStyle, WritingMode aWM, - nscoord aContentSize, bool aIsSubgridded); + nscoord aContentBoxSize, bool aIsSubgridded); nscoord GridLineEdge(uint32_t aLine, GridLineSide aSide) const { if (MOZ_UNLIKELY(mSizes.IsEmpty())) { @@ -3010,20 +3010,23 @@ void nsGridContainerFrame::UsedTrackSizes::ResolveTrackSizesForAxis( mCanResolveLineRangeSize[aAxis] = true; } else { const auto& range = subgrid->mArea.LineRangeForAxis(parentAxis); - nscoord cbSize = range.ToLength(parentSizes->mSizes[parentAxis]); - ResolveSubgridTrackSizesForAxis(aFrame, aAxis, subgrid, aRC, cbSize); + nscoord contentBoxSize = range.ToLength(parentSizes->mSizes[parentAxis]); + auto parentWM = aFrame->GetParent()->GetWritingMode(); + contentBoxSize -= subgrid->mMarginBorderPadding.StartEnd(parentAxis, parentWM); + contentBoxSize = std::max(nscoord(0), contentBoxSize); + ResolveSubgridTrackSizesForAxis(aFrame, aAxis, subgrid, aRC, contentBoxSize); } } void nsGridContainerFrame::UsedTrackSizes::ResolveSubgridTrackSizesForAxis( nsGridContainerFrame* aFrame, LogicalAxis aAxis, Subgrid* aSubgrid, - gfxContext& aRC, nscoord aCBSize) { + gfxContext& aRC, nscoord aContentBoxSize) { GridReflowInput state(aFrame, aRC); state.mGridItems = aSubgrid->mGridItems; Grid grid; grid.mGridColEnd = aSubgrid->mGridColEnd; grid.mGridRowEnd = aSubgrid->mGridRowEnd; - state.CalculateTrackSizesForAxis(aAxis, grid, aCBSize, + state.CalculateTrackSizesForAxis(aAxis, grid, aContentBoxSize, SizingConstraint::NoConstraint); const auto& tracks = aAxis == eLogicalAxisInline ? state.mCols : state.mRows; mSizes[aAxis] = tracks.mSizes; @@ -3032,7 +3035,7 @@ void nsGridContainerFrame::UsedTrackSizes::ResolveSubgridTrackSizesForAxis( } void nsGridContainerFrame::GridReflowInput::CalculateTrackSizesForAxis( - LogicalAxis aAxis, const Grid& aGrid, nscoord aContentSize, + LogicalAxis aAxis, const Grid& aGrid, nscoord aContentBoxSize, SizingConstraint aConstraint) { auto& tracks = aAxis == eLogicalAxisInline ? mCols : mRows; const auto& sizingFunctions = @@ -3046,10 +3049,10 @@ void nsGridContainerFrame::GridReflowInput::CalculateTrackSizesForAxis( bool useParentGaps = false; const bool isSubgriddedAxis = mFrame->IsSubgrid(aAxis); if (MOZ_LIKELY(!isSubgriddedAxis)) { - tracks.Initialize(sizingFunctions, gapStyle, gridEnd, aContentSize); + tracks.Initialize(sizingFunctions, gapStyle, gridEnd, aContentBoxSize); } else { - tracks.mGridGap = nsLayoutUtils::ResolveGapToLength(gapStyle, aContentSize); - tracks.mContentBoxSize = aContentSize; + tracks.mGridGap = nsLayoutUtils::ResolveGapToLength(gapStyle, aContentBoxSize); + tracks.mContentBoxSize = aContentBoxSize; const auto* subgrid = mFrame->GetProperty(Subgrid::Prop()); tracks.mSizes.SetLength(gridEnd); auto* parent = mFrame->ParentGridContainerForSubgrid(); @@ -3068,7 +3071,7 @@ void nsGridContainerFrame::GridReflowInput::CalculateTrackSizesForAxis( *fallbackTrackSizing->mAutoMaxSizing, fallbackTrackSizing->mHasRepeatAuto, fallbackTrackSizing->mRepeatAutoIndex), - gapStyle, gridEnd, aContentSize); + gapStyle, gridEnd, aContentBoxSize); } } @@ -3089,7 +3092,7 @@ void nsGridContainerFrame::GridReflowInput::CalculateTrackSizesForAxis( fallbackTrackSizing->mHasRepeatAuto, fallbackTrackSizing->mRepeatAutoIndex) : sizingFunctions, - aContentSize, + aContentBoxSize, aAxis == eLogicalAxisInline ? &GridArea::mCols : &GridArea::mRows, aConstraint); // XXXmats we're losing the baseline state of subgrid descendants that @@ -3098,8 +3101,8 @@ void nsGridContainerFrame::GridReflowInput::CalculateTrackSizesForAxis( mGridItems.TruncateLength(origGridItemCount); } - if (aContentSize != NS_UNCONSTRAINEDSIZE) { - tracks.AlignJustifyContent(mGridStyle, mWM, aContentSize, isSubgriddedAxis); + if (aContentBoxSize != NS_UNCONSTRAINEDSIZE) { + tracks.AlignJustifyContent(mGridStyle, mWM, aContentBoxSize, isSubgriddedAxis); } else if (!useParentGaps) { const nscoord gridGap = tracks.mGridGap; nscoord pos = 0; @@ -5612,7 +5615,7 @@ void nsGridContainerFrame::Tracks::StretchFlexibleTracks( } void nsGridContainerFrame::Tracks::AlignJustifyContent( - const nsStylePosition* aStyle, WritingMode aWM, nscoord aContentSize, + const nsStylePosition* aStyle, WritingMode aWM, nscoord aContentBoxSize, bool aIsSubgriddedAxis) { const bool isAlign = mAxis == eLogicalAxisBlock; // Align-/justify-content doesn't apply in a subgridded axis. @@ -5702,7 +5705,7 @@ void nsGridContainerFrame::Tracks::AlignJustifyContent( } } } - space = aContentSize - trackSizeSum - SumOfGridGaps(); + space = aContentBoxSize - trackSizeSum - SumOfGridGaps(); // Use the fallback value instead when applicable. if (space < 0 || (alignment == NS_STYLE_ALIGN_SPACE_BETWEEN && mSizes.Length() == 1)) { diff --git a/testing/web-platform/tests/css/css-grid/subgrid/auto-track-sizing-001-ref.html b/testing/web-platform/tests/css/css-grid/subgrid/auto-track-sizing-001-ref.html new file mode 100644 index 0000000000000..800f87e5d00a7 --- /dev/null +++ b/testing/web-platform/tests/css/css-grid/subgrid/auto-track-sizing-001-ref.html @@ -0,0 +1,65 @@ + + + + + Reference: subgrid auto track sizing + + + + + +
+
+ The cat can not be separated from milk +
+
+ +
+
+ The cat can not be separated from milk +
+
+ +
+
+ The cat can not be separated from milk +
+
+ +
+
+ The cat can not be separated from milk +
+
+ +
+
+ The cat can not be separated from milk +
+
+ + + diff --git a/testing/web-platform/tests/css/css-grid/subgrid/auto-track-sizing-001.html b/testing/web-platform/tests/css/css-grid/subgrid/auto-track-sizing-001.html new file mode 100644 index 0000000000000..0fdb9b0b7e2ed --- /dev/null +++ b/testing/web-platform/tests/css/css-grid/subgrid/auto-track-sizing-001.html @@ -0,0 +1,68 @@ + + + + + Test: subgrid auto track sizing + + + + + + + +
+
+ The cat can not be separated from milk +
+
+ +
+
+ The cat can not be separated from milk +
+
+ +
+
+ The cat can not be separated from milk +
+
+ +
+
+ The cat can not be separated from milk +
+
+ +
+
+ The cat can not be separated from milk +
+
+ + + From f49588e469b6d15fb5c80daaeb62734ce8f29323 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Wed, 19 Jun 2019 11:27:02 -0700 Subject: [PATCH 08/14] Bug 1560166: Part 1 - Stop using UUIDs for DOM reference IDs. r=mconley UUIDs are expensive to create, to use as map keys, and to transfer between processes. They are also completely unnecessary for this use case, since the number returned by Math.random() has the same characteristics that we're depending on the UUID generator for, only with better performance. That said, even Math.random() is probably overkill for this use case, when we can just use continually incremented serial number and get the same behavior, but I decided to continue using randomized IDs mainly to minimize the magnitude of the change. --- toolkit/modules/ContentDOMReference.jsm | 63 +++++++++++++------------ 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/toolkit/modules/ContentDOMReference.jsm b/toolkit/modules/ContentDOMReference.jsm index b46c91b0f6be5..f332f3495240b 100644 --- a/toolkit/modules/ContentDOMReference.jsm +++ b/toolkit/modules/ContentDOMReference.jsm @@ -18,20 +18,21 @@ var EXPORTED_SYMBOLS = ["ContentDOMReference"]; const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); -XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator", - "@mozilla.org/uuid-generator;1", - "nsIUUIDGenerator"); +/** + * @typedef {number} ElementID + * @typedef {Object} ElementIdentifier + */ /** * An identifier generated by ContentDOMReference is a unique pair of BrowsingContext - * ID and a UUID. gRegistry maps BrowsingContext's to an object with the following + * ID and a numeric ID. gRegistry maps BrowsingContext's to an object with the following * properties: * - * UUIDToElement: - * A Map of UUID strings to WeakReference's to the elements they refer to. + * IDToElement: + * A Map of IDs to WeakReference's to the elements they refer to. * - * elementToUUID: - * A WeakMap from a DOM element to a UUID that refers to it. + * elementToID: + * A WeakMap from a DOM element to an ID that refers to it. */ var gRegistry = new WeakMap(); @@ -40,7 +41,7 @@ var ContentDOMReference = { * Generate and return an identifier for a given DOM element. * * @param {Element} element The DOM element to generate the identifier for. - * @return {Object} The identifier for the DOM element that can be passed between + * @return {ElementIdentifier} The identifier for the DOM element that can be passed between * processes as a message. */ get(element) { @@ -53,38 +54,38 @@ var ContentDOMReference = { let mappings = gRegistry.get(browsingContext); if (!mappings) { mappings = { - UUIDToElement: new Map(), - elementToUUID: new WeakMap(), + IDToElement: new Map(), + elementToID: new WeakMap(), }; gRegistry.set(browsingContext, mappings); } - let uuid = mappings.elementToUUID.get(element); - if (uuid) { - // We already had this element registered, so return the pre-existing UUID. - return { browsingContextId: browsingContext.id, uuid }; + let id = mappings.elementToID.get(element); + if (id) { + // We already had this element registered, so return the pre-existing ID. + return { browsingContextId: browsingContext.id, id }; } // We must be registering a new element at this point. - uuid = gUUIDGenerator.generateUUID().toString(); - mappings.elementToUUID.set(element, uuid); - mappings.UUIDToElement.set(uuid, Cu.getWeakReference(element)); + id = Math.random(); + mappings.elementToID.set(element, id); + mappings.IDToElement.set(id, Cu.getWeakReference(element)); - return { browsingContextId: browsingContext.id, uuid }; + return { browsingContextId: browsingContext.id, id }; }, /** * Resolves an identifier back into the DOM Element that it was generated from. * - * @param {Object} The identifier generated via ContentDOMReference.get for a + * @param {ElementIdentifier} The identifier generated via ContentDOMReference.get for a * DOM element. * @return {Element} The DOM element that the identifier was generated for, or * null if the element does not still exist. */ resolve(identifier) { let browsingContext = BrowsingContext.get(identifier.browsingContextId); - let uuid = identifier.uuid; - return this._resolveUUIDToElement(browsingContext, uuid); + let {id} = identifier; + return this._resolveIDToElement(browsingContext, id); }, /** @@ -94,44 +95,44 @@ var ContentDOMReference = { * DOM element alive, but the weak pointers themselves consume memory, and * that's what we reclaim when revoking). * - * @param {Object} The identifier to revoke, issued by ContentDOMReference.get for + * @param {ElementIdentifier} The identifier to revoke, issued by ContentDOMReference.get for * a DOM element. */ revoke(identifier) { let browsingContext = BrowsingContext.get(identifier.browsingContextId); - let uuid = identifier.uuid; + let {id} = identifier; let mappings = gRegistry.get(browsingContext); if (!mappings) { return; } - let element = this._resolveUUIDToElement(browsingContext, uuid); + let element = this._resolveIDToElement(browsingContext, id); if (element) { - mappings.elementToUUID.delete(element); + mappings.elementToID.delete(element); } - mappings.UUIDToElement.delete(uuid); + mappings.IDToElement.delete(id); }, /** - * Private helper function that resolves a BrowsingContext and UUID (the + * Private helper function that resolves a BrowsingContext and ID (the * pair that makes up an identifier) to a DOM element. * * @param {BrowsingContext} browsingContext The BrowsingContext that was hosting * the DOM element at the time that the identifier was generated. - * @param {String} uuid The UUID generated for the DOM element. + * @param {ElementID} id The ID generated for the DOM element. * * @return {Element} The DOM element that the identifier was generated for, or * null if the element does not still exist. */ - _resolveUUIDToElement(browsingContext, uuid) { + _resolveIDToElement(browsingContext, id) { let mappings = gRegistry.get(browsingContext); if (!mappings) { return null; } - let weakReference = mappings.UUIDToElement.get(uuid); + let weakReference = mappings.IDToElement.get(id); if (!weakReference) { return null; } From ffafe50991fadebd491653004110c5228de86704 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Wed, 19 Jun 2019 12:06:38 -0700 Subject: [PATCH 09/14] Bug 1560166: Part 2 - Add finalization witness to cleanup dead references. r=mconley Requiring callers to manually cleanup all DOM references that they create runs counter to the usual JavaScript model of automatic garbage collection, where developers usually do not need to think about manual deallocation. It's bound to lead to leaks before long. This patch adds a finalization witness bound to the element of any DOM reference that we create. When that element is destroyed, the finalization witness also removes its entry from the ID map. Since the mappings are already stored as weak references, this shouldn't result in a change to the behavior that callers see, only in the underlying memory management. It essentially makes this behave as a true weak value map. Differential Revision: https://phabricator.services.mozilla.com/D35354 --- toolkit/modules/ContentDOMReference.jsm | 38 ++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/toolkit/modules/ContentDOMReference.jsm b/toolkit/modules/ContentDOMReference.jsm index f332f3495240b..1a87cf20fcc9d 100644 --- a/toolkit/modules/ContentDOMReference.jsm +++ b/toolkit/modules/ContentDOMReference.jsm @@ -18,11 +18,23 @@ var EXPORTED_SYMBOLS = ["ContentDOMReference"]; const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); +XPCOMUtils.defineLazyServiceGetter(this, "finalizationService", + "@mozilla.org/toolkit/finalizationwitness;1", + "nsIFinalizationWitnessService"); + /** * @typedef {number} ElementID * @typedef {Object} ElementIdentifier */ +const FINALIZATION_TOPIC = "content-dom-reference-finalized"; + +// A WeakMap which ties finalization witness objects to the lifetime of the DOM +// nodes they're meant to witness. When the DOM node in the map key is +// finalized, the WeakMap stops holding the finalization witness in its value +// alive, which alerts our observer that the element has been destroyed. +const finalizerRoots = new WeakMap(); + /** * An identifier generated by ContentDOMReference is a unique pair of BrowsingContext * ID and a numeric ID. gRegistry maps BrowsingContext's to an object with the following @@ -37,6 +49,20 @@ const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm") var gRegistry = new WeakMap(); var ContentDOMReference = { + _init() { + const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); + Services.obs.addObserver(this, FINALIZATION_TOPIC); + }, + + observe(subject, topic, data) { + if (topic !== FINALIZATION_TOPIC) { + throw new Error("Unexpected observer topic"); + } + + let identifier = JSON.parse(data); + this.revoke(identifier); + }, + /** * Generate and return an identifier for a given DOM element. * @@ -71,7 +97,14 @@ var ContentDOMReference = { mappings.elementToID.set(element, id); mappings.IDToElement.set(id, Cu.getWeakReference(element)); - return { browsingContextId: browsingContext.id, id }; + let identifier = { browsingContextId: browsingContext.id, id }; + + finalizerRoots.set( + element, + finalizationService.make(FINALIZATION_TOPIC, + JSON.stringify(identifier))); + + return identifier; }, /** @@ -110,6 +143,7 @@ var ContentDOMReference = { let element = this._resolveIDToElement(browsingContext, id); if (element) { mappings.elementToID.delete(element); + finalizerRoots.delete(element); } mappings.IDToElement.delete(id); @@ -140,3 +174,5 @@ var ContentDOMReference = { return weakReference.get(); }, }; + +ContentDOMReference._init(); From ecd74a38194ebe1821f0ed00b381fd5e9ce817c9 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Wed, 19 Jun 2019 17:55:33 -0700 Subject: [PATCH 10/14] Bug 1560166: Part 3 - Make unused revoke() method non-public. r=mconley Differential Revision: https://phabricator.services.mozilla.com/D35391 --- toolkit/modules/ContentDOMReference.jsm | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/toolkit/modules/ContentDOMReference.jsm b/toolkit/modules/ContentDOMReference.jsm index 1a87cf20fcc9d..5db1cf08f4fb9 100644 --- a/toolkit/modules/ContentDOMReference.jsm +++ b/toolkit/modules/ContentDOMReference.jsm @@ -60,7 +60,7 @@ var ContentDOMReference = { } let identifier = JSON.parse(data); - this.revoke(identifier); + this._revoke(identifier); }, /** @@ -123,15 +123,13 @@ var ContentDOMReference = { /** * Removes an identifier from the registry so that subsequent attempts - * to resolve it will result in null. This is generally a good idea to avoid - * identifiers lying around taking up space (identifiers don't keep the - * DOM element alive, but the weak pointers themselves consume memory, and - * that's what we reclaim when revoking). + * to resolve it will result in null. This is done automatically when the + * target node is GCed. * * @param {ElementIdentifier} The identifier to revoke, issued by ContentDOMReference.get for * a DOM element. */ - revoke(identifier) { + _revoke(identifier) { let browsingContext = BrowsingContext.get(identifier.browsingContextId); let {id} = identifier; @@ -140,12 +138,6 @@ var ContentDOMReference = { return; } - let element = this._resolveIDToElement(browsingContext, id); - if (element) { - mappings.elementToID.delete(element); - finalizerRoots.delete(element); - } - mappings.IDToElement.delete(id); }, From 30479841bf155b0adcd632891dd49a888242ee19 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Thu, 20 Jun 2019 15:40:35 -0700 Subject: [PATCH 11/14] Bug 1530660: Fix registration for nsSafeFileOutputStream. r=erahm Differential Revision: https://phabricator.services.mozilla.com/D35490 --- netwerk/build/components.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netwerk/build/components.conf b/netwerk/build/components.conf index aa930f1c862e0..bfd27e3336bbb 100644 --- a/netwerk/build/components.conf +++ b/netwerk/build/components.conf @@ -340,7 +340,7 @@ Classes = [ { 'cid': '{a181af0d-68b8-4308-94db-d4f859058215}', 'contract_ids': ['@mozilla.org/network/safe-file-output-stream;1'], - 'type': 'nsAtomicFileOutputStream', + 'type': 'nsSafeFileOutputStream', 'headers': ['nsFileStreams.h'], }, { From 9557de9d1acf03fb8aa829a7438c1e7a1a42bea5 Mon Sep 17 00:00:00 2001 From: myfreeweb Date: Thu, 20 Jun 2019 16:18:45 -0400 Subject: [PATCH 12/14] Bug 1213601 - implement kinetic/inertial scrolling (fling) for Gtk. r=botond --- gfx/layers/apz/src/AsyncPanZoomController.cpp | 45 ++++++++++++-- gfx/layers/ipc/LayersMessageUtils.h | 19 ------ ipc/glue/IPCMessageUtils.h | 19 ++++++ modules/libpref/init/StaticPrefList.h | 9 +++ widget/InputData.cpp | 25 +++++++- widget/InputData.h | 33 ++++++++-- widget/gtk/nsWindow.cpp | 61 ++++++++++++++++--- widget/gtk/nsWindow.h | 2 + widget/nsBaseWidget.cpp | 23 +++++++ widget/nsBaseWidget.h | 8 +++ widget/nsGUIEventIPC.h | 32 +++++++--- 11 files changed, 226 insertions(+), 50 deletions(-) diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index f6ecc7b991444..28fbed0af7404 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -1822,8 +1822,8 @@ nsEventStatus AsyncPanZoomController::OnScaleEnd( } nsEventStatus AsyncPanZoomController::HandleEndOfPan() { - MOZ_ASSERT(GetCurrentTouchBlock()); - GetCurrentTouchBlock()->GetOverscrollHandoffChain()->FlushRepaints(); + MOZ_ASSERT(GetCurrentTouchBlock() || GetCurrentPanGestureBlock()); + GetCurrentInputBlock()->GetOverscrollHandoffChain()->FlushRepaints(); ParentLayerPoint flingVelocity = GetVelocityVector(); // Clear our velocities; if DispatchFling() gives the fling to us, @@ -1845,7 +1845,7 @@ nsEventStatus AsyncPanZoomController::HandleEndOfPan() { if (flingVelocity.Length() < StaticPrefs::APZFlingMinVelocityThreshold()) { // Relieve overscroll now if needed, since we will not transition to a fling // animation and then an overscroll animation, and relieve it then. - GetCurrentTouchBlock() + GetCurrentInputBlock() ->GetOverscrollHandoffChain() ->SnapBackOverscrolledApzc(this); return nsEventStatus_eConsumeNoDefault; @@ -1856,8 +1856,8 @@ nsEventStatus AsyncPanZoomController::HandleEndOfPan() { // which nulls out mTreeManager, could be called concurrently. if (APZCTreeManager* treeManagerLocal = GetApzcTreeManager()) { const FlingHandoffState handoffState{ - flingVelocity, GetCurrentTouchBlock()->GetOverscrollHandoffChain(), - false /* not handoff */, GetCurrentTouchBlock()->GetScrolledApzc()}; + flingVelocity, GetCurrentInputBlock()->GetOverscrollHandoffChain(), + false /* not handoff */, GetCurrentInputBlock()->GetScrolledApzc()}; treeManagerLocal->DispatchFling(this, handoffState); } return nsEventStatus_eConsumeNoDefault; @@ -2556,6 +2556,35 @@ nsEventStatus AsyncPanZoomController::OnPan(const PanGestureInput& aEvent, ScreenPoint physicalPanDisplacement = aEvent.mPanDisplacement; ParentLayerPoint logicalPanDisplacement = aEvent.UserMultipliedLocalPanDisplacement(); + if (aEvent.mDeltaType == PanGestureInput::PANDELTA_PAGE) { + // Pan events with page units are used by Gtk, so this replicates Gtk: + // https://gitlab.gnome.org/GNOME/gtk/blob/c734c7e9188b56f56c3a504abee05fa40c5475ac/gtk/gtkrange.c#L3065-3073 + CSSSize pageScrollSize; + CSSToParentLayerScale2D zoom; + { + // Grab the lock to access the frame metrics. + RecursiveMutexAutoLock lock(mRecursiveMutex); + pageScrollSize = mScrollMetadata.GetPageScrollAmount() / + Metrics().GetDevPixelsPerCSSPixel(); + zoom = Metrics().GetZoom(); + } + // scrollUnit* is in units of "ParentLayer pixels per page proportion"... + auto scrollUnitWidth = std::min(std::pow(pageScrollSize.width, 2.0 / 3.0), + pageScrollSize.width / 2.0) * + zoom.xScale; + auto scrollUnitHeight = std::min(std::pow(pageScrollSize.height, 2.0 / 3.0), + pageScrollSize.height / 2.0) * + zoom.yScale; + // ... and pan displacements are in units of "page proportion count" + // here, so the products of them and scrollUnit* are in ParentLayer pixels + ParentLayerPoint physicalPanDisplacementPL( + physicalPanDisplacement.x * scrollUnitWidth, + physicalPanDisplacement.y * scrollUnitHeight); + physicalPanDisplacement = ToScreenCoordinates(physicalPanDisplacementPL, + aEvent.mLocalPanStartPoint); + logicalPanDisplacement.x *= scrollUnitWidth; + logicalPanDisplacement.y *= scrollUnitHeight; + } MOZ_ASSERT(GetCurrentPanGestureBlock()); AdjustDeltaForAllowedScrollDirections( @@ -2609,6 +2638,12 @@ nsEventStatus AsyncPanZoomController::OnPanEnd(const PanGestureInput& aEvent) { mX.EndTouch(aEvent.mTime); mY.EndTouch(aEvent.mTime); + // Use HandleEndOfPan for fling on platforms that don't + // emit momentum events (Gtk). + if (aEvent.mSimulateMomentum) { + return HandleEndOfPan(); + } + // Drop any velocity on axes where we don't have room to scroll anyways // (in this APZC, or an APZC further in the handoff chain). // This ensures that we don't enlarge the display port unnecessarily. diff --git a/gfx/layers/ipc/LayersMessageUtils.h b/gfx/layers/ipc/LayersMessageUtils.h index 0ba8ac2165e68..67d39e6cbb545 100644 --- a/gfx/layers/ipc/LayersMessageUtils.h +++ b/gfx/layers/ipc/LayersMessageUtils.h @@ -167,25 +167,6 @@ struct ParamTraits { } }; -// Helper class for reading bitfields. -// If T has bitfields members, derive ParamTraits from BitfieldHelper. -template -struct BitfieldHelper { - // We need this helper because we can't get the address of a bitfield to - // pass directly to ReadParam. So instead we read it into a temporary bool - // and set the bitfield using a setter function - static bool ReadBoolForBitfield(const Message* aMsg, PickleIterator* aIter, - ParamType* aResult, - void (ParamType::*aSetter)(bool)) { - bool value; - if (ReadParam(aMsg, aIter, &value)) { - (aResult->*aSetter)(value); - return true; - } - return false; - } -}; - template <> struct ParamTraits : BitfieldHelper { diff --git a/ipc/glue/IPCMessageUtils.h b/ipc/glue/IPCMessageUtils.h index 86604566e4692..047d154601589 100644 --- a/ipc/glue/IPCMessageUtils.h +++ b/ipc/glue/IPCMessageUtils.h @@ -1088,6 +1088,25 @@ struct ParamTraits : EnumSerializer {}; +// Helper class for reading bitfields. +// If T has bitfields members, derive ParamTraits from BitfieldHelper. +template +struct BitfieldHelper { + // We need this helper because we can't get the address of a bitfield to + // pass directly to ReadParam. So instead we read it into a temporary bool + // and set the bitfield using a setter function + static bool ReadBoolForBitfield(const Message* aMsg, PickleIterator* aIter, + ParamType* aResult, + void (ParamType::*aSetter)(bool)) { + bool value; + if (ReadParam(aMsg, aIter, &value)) { + (aResult->*aSetter)(value); + return true; + } + return false; + } +}; + } /* namespace IPC */ #endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */ diff --git a/modules/libpref/init/StaticPrefList.h b/modules/libpref/init/StaticPrefList.h index 2c6491db29d42..d3ba68d5c88c8 100644 --- a/modules/libpref/init/StaticPrefList.h +++ b/modules/libpref/init/StaticPrefList.h @@ -406,6 +406,15 @@ VARCACHE_PREF( RelaxedAtomicBool, false ) +#ifdef MOZ_WIDGET_GTK +VARCACHE_PREF( + Live, + "apz.gtk.kinetic_scroll.enabled", + APZGTKKineticScrollEnabled, + RelaxedAtomicBool, false +) +#endif + #if !defined(MOZ_WIDGET_ANDROID) # define PREF_VALUE true #else diff --git a/widget/InputData.cpp b/widget/InputData.cpp index 2205ff5216a65..3f5ac85bb8e07 100644 --- a/widget/InputData.cpp +++ b/widget/InputData.cpp @@ -437,7 +437,8 @@ PanGestureInput::PanGestureInput() mHandledByAPZ(false), mFollowedByMomentum(false), mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false), - mOverscrollBehaviorAllowsSwipe(false) {} + mOverscrollBehaviorAllowsSwipe(false), + mSimulateMomentum(false) {} PanGestureInput::PanGestureInput(PanGestureType aType, uint32_t aTime, TimeStamp aTimeStamp, @@ -455,7 +456,8 @@ PanGestureInput::PanGestureInput(PanGestureType aType, uint32_t aTime, mHandledByAPZ(false), mFollowedByMomentum(false), mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false), - mOverscrollBehaviorAllowsSwipe(false) {} + mOverscrollBehaviorAllowsSwipe(false), + mSimulateMomentum(false) {} bool PanGestureInput::IsMomentum() const { switch (mType) { @@ -477,7 +479,6 @@ WidgetWheelEvent PanGestureInput::ToWidgetWheelEvent(nsIWidget* aWidget) const { mPanStartPoint, PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent)); wheelEvent.mButtons = 0; - wheelEvent.mDeltaMode = WheelEvent_Binding::DOM_DELTA_PIXEL; wheelEvent.mMayHaveMomentum = true; // pan inputs may have momentum wheelEvent.mIsMomentum = IsMomentum(); wheelEvent.mLineOrPageDeltaX = mLineOrPageDeltaX; @@ -486,6 +487,16 @@ WidgetWheelEvent PanGestureInput::ToWidgetWheelEvent(nsIWidget* aWidget) const { wheelEvent.mDeltaY = mPanDisplacement.y; wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ; wheelEvent.mFocusSequenceNumber = mFocusSequenceNumber; + if (mDeltaType == PanGestureInput::PANDELTA_PAGE) { + // Emulate legacy widget/gtk behavior + wheelEvent.mDeltaMode = WheelEvent_Binding::DOM_DELTA_LINE; + wheelEvent.mIsNoLineOrPageDelta = true; + wheelEvent.mScrollType = WidgetWheelEvent::SCROLL_ASYNCHRONOUSELY; + wheelEvent.mDeltaX *= 3; + wheelEvent.mDeltaY *= 3; + } else { + wheelEvent.mDeltaMode = WheelEvent_Binding::DOM_DELTA_PIXEL; + } return wheelEvent; } @@ -498,6 +509,14 @@ bool PanGestureInput::TransformToLocal( } mLocalPanStartPoint = *panStartPoint; + if (mDeltaType == PanGestureInput::PANDELTA_PAGE) { + // Skip transforming the pan displacement because we want + // raw page proportion counts. + mLocalPanDisplacement.x = mPanDisplacement.x; + mLocalPanDisplacement.y = mPanDisplacement.y; + return true; + } + Maybe panDisplacement = UntransformVector(aTransform, mPanDisplacement, mPanStartPoint); if (!panDisplacement) { diff --git a/widget/InputData.h b/widget/InputData.h index eb579bc8147fe..fc87949cc80aa 100644 --- a/widget/InputData.h +++ b/widget/InputData.h @@ -332,6 +332,17 @@ class PanGestureInput : public InputData { // user has stopped the animation by putting their fingers on a touchpad. PANGESTURE_MOMENTUMEND )); + + MOZ_DEFINE_ENUM_AT_CLASS_SCOPE( + PanDeltaType, ( + // There are three kinds of scroll delta modes in Gecko: "page", "line" + // and "pixel". Touchpad pan gestures only support "page" and "pixel". + // + // NOTE: PANDELTA_PAGE currently replicates Gtk behavior + // (see AsyncPanZoomController::OnPan). + PANDELTA_PAGE, + PANDELTA_PIXEL + )); // clang-format on PanGestureInput(PanGestureType aType, uint32_t aTime, TimeStamp aTimeStamp, @@ -368,11 +379,13 @@ class PanGestureInput : public InputData { double mUserDeltaMultiplierX; double mUserDeltaMultiplierY; - bool mHandledByAPZ; + PanDeltaType mDeltaType = PANDELTA_PIXEL; + + bool mHandledByAPZ: 1; // true if this is a PANGESTURE_END event that will be followed by a // PANGESTURE_MOMENTUMSTART event. - bool mFollowedByMomentum; + bool mFollowedByMomentum: 1; // If this is true, and this event started a new input block that couldn't // find a scrollable target which is scrollable in the horizontal component @@ -380,15 +393,25 @@ class PanGestureInput : public InputData { // hold until a content response has arrived, even if the block has a // confirmed target. // This is used by events that can result in a swipe instead of a scroll. - bool mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection; + bool mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection: 1; // This is used by APZ to communicate to the macOS widget code whether // the overscroll-behavior of the scroll frame handling this swipe allows // non-local overscroll behaviors in the horizontal direction (such as // swipe navigation). - bool mOverscrollBehaviorAllowsSwipe; + bool mOverscrollBehaviorAllowsSwipe: 1; - // XXX: If adding any more bools, switch to using bitfields instead. + // true if APZ should do a fling animation after this pan ends, like + // it would with touchscreens. (For platforms that don't emit momentum events.) + bool mSimulateMomentum: 1; + + void SetHandledByAPZ(bool aHandled) { mHandledByAPZ = aHandled; } + void SetFollowedByMomentum(bool aFollowed) { mFollowedByMomentum = aFollowed; } + void SetRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(bool aRequires) { + mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection = aRequires; + } + void SetOverscrollBehaviorAllowsSwipe(bool aAllows) { mOverscrollBehaviorAllowsSwipe = aAllows; } + void SetSimulateMomentum(bool aSimulate) { mSimulateMomentum = aSimulate; } }; /** diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index e0c7536e330b3..1537c452cbac1 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -119,6 +119,9 @@ using namespace mozilla::widget; #include "mozilla/layers/CompositorThread.h" #include "mozilla/layers/KnowsCompositor.h" +#include "mozilla/layers/APZInputBridge.h" +#include "mozilla/layers/IAPZCTreeManager.h" + #ifdef MOZ_X11 # include "GLContextGLX.h" // for GLContextGLX::FindVisual() # include "GtkCompositorWidget.h" @@ -3034,8 +3037,11 @@ void nsWindow::OnScrollEvent(GdkEventScroll* aEvent) { #if GTK_CHECK_VERSION(3, 4, 0) // check for duplicate legacy scroll event, see GNOME bug 726878 if (aEvent->direction != GDK_SCROLL_SMOOTH && - mLastScrollEventTime == aEvent->time) + mLastScrollEventTime == aEvent->time) { + LOG(("[%d] duplicate legacy scroll event %d\n", aEvent->time, + aEvent->direction)); return; + } #endif WidgetWheelEvent wheelEvent(true, eWheel, this); wheelEvent.mDeltaMode = dom::WheelEvent_Binding::DOM_DELTA_LINE; @@ -3043,21 +3049,56 @@ void nsWindow::OnScrollEvent(GdkEventScroll* aEvent) { #if GTK_CHECK_VERSION(3, 4, 0) case GDK_SCROLL_SMOOTH: { // As of GTK 3.4, all directional scroll events are provided by - // the GDK_SCROLL_SMOOTH direction on XInput2 devices. + // the GDK_SCROLL_SMOOTH direction on XInput2 and Wayland devices. mLastScrollEventTime = aEvent->time; - // TODO - use a more appropriate scrolling unit than lines. - // Multiply event deltas by 3 to emulate legacy behaviour. - wheelEvent.mDeltaX = aEvent->delta_x * 3; - wheelEvent.mDeltaY = aEvent->delta_y * 3; - wheelEvent.mIsNoLineOrPageDelta = true; - // This next step manually unsets smooth scrolling for touch devices - // that trigger GDK_SCROLL_SMOOTH. We use the slave device, which - // represents the actual input. + + // Special handling for touchpads to support flings + // (also known as kinetic/inertial/momentum scrolling) GdkDevice* device = gdk_event_get_source_device((GdkEvent*)aEvent); GdkInputSource source = gdk_device_get_source(device); if (source == GDK_SOURCE_TOUCHSCREEN || source == GDK_SOURCE_TOUCHPAD) { + if (StaticPrefs::APZGTKKineticScrollEnabled() && + gtk_check_version(3, 20, 0) == nullptr) { + static auto sGdkEventIsScrollStopEvent = + (gboolean(*)(const GdkEvent*))dlsym( + RTLD_DEFAULT, "gdk_event_is_scroll_stop_event"); + + LOG(("[%d] pan smooth event dx=%f dy=%f inprogress=%d\n", + aEvent->time, aEvent->delta_x, aEvent->delta_y, mPanInProgress)); + PanGestureInput::PanGestureType eventType = + PanGestureInput::PANGESTURE_PAN; + if (sGdkEventIsScrollStopEvent((GdkEvent*)aEvent)) { + eventType = PanGestureInput::PANGESTURE_END; + mPanInProgress = false; + } else if (!mPanInProgress) { + eventType = PanGestureInput::PANGESTURE_START; + mPanInProgress = true; + } + + LayoutDeviceIntPoint touchPoint = GetRefPoint(this, aEvent); + PanGestureInput panEvent( + eventType, aEvent->time, GetEventTimeStamp(aEvent->time), + ScreenPoint(touchPoint.x, touchPoint.y), + ScreenPoint(aEvent->delta_x, aEvent->delta_y), + KeymapWrapper::ComputeKeyModifiers(aEvent->state)); + panEvent.mDeltaType = PanGestureInput::PANDELTA_PAGE; + panEvent.mSimulateMomentum = true; + + DispatchPanGestureInput(panEvent); + + return; + } + + // Older GTK doesn't support stop events, so we can't support fling wheelEvent.mScrollType = WidgetWheelEvent::SCROLL_ASYNCHRONOUSELY; } + + // TODO - use a more appropriate scrolling unit than lines. + // Multiply event deltas by 3 to emulate legacy behaviour. + wheelEvent.mDeltaX = aEvent->delta_x * 3; + wheelEvent.mDeltaY = aEvent->delta_y * 3; + wheelEvent.mIsNoLineOrPageDelta = true; + break; } #endif diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index 64e7effa61d94..98b740eb23851 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -492,6 +492,8 @@ class nsWindow final : public nsBaseWidget { // This field omits duplicate scroll events caused by GNOME bug 726878. guint32 mLastScrollEventTime; + bool mPanInProgress = false; + // for touch event handling nsRefPtrHashtable, mozilla::dom::Touch> mTouches; diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp index a6fa8d8613871..2627300b46f52 100644 --- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -1132,6 +1132,29 @@ void nsBaseWidget::DispatchTouchInput(MultiTouchInput& aInput) { } } +void nsBaseWidget::DispatchPanGestureInput(PanGestureInput& aInput) { + MOZ_ASSERT(NS_IsMainThread()); + if (mAPZC) { + MOZ_ASSERT(APZThreadUtils::IsControllerThread()); + uint64_t inputBlockId = 0; + ScrollableLayerGuid guid; + + nsEventStatus result = + mAPZC->InputBridge()->ReceiveInputEvent(aInput, &guid, &inputBlockId); + if (result == nsEventStatus_eConsumeNoDefault) { + return; + } + + WidgetWheelEvent event = aInput.ToWidgetWheelEvent(this); + ProcessUntransformedAPZEvent(&event, guid, inputBlockId, result); + } else { + WidgetWheelEvent event = aInput.ToWidgetWheelEvent(this); + + nsEventStatus status; + DispatchEvent(&event, status); + } +} + nsEventStatus nsBaseWidget::DispatchInputEvent(WidgetInputEvent* aEvent) { MOZ_ASSERT(NS_IsMainThread()); if (mAPZC) { diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index 2972d341c50cc..fbc5ccf44138c 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -619,6 +619,14 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference { */ void DispatchTouchInput(mozilla::MultiTouchInput& aInput); + /** + * Dispatch the given PanGestureInput through APZ to Gecko (if APZ is enabled) + * or directly to gecko (if APZ is not enabled). This function must only + * be called from the main thread, and if APZ is enabled, that must also be + * the APZ controller thread. + */ + void DispatchPanGestureInput(mozilla::PanGestureInput& aInput); + #if defined(XP_WIN) void UpdateScrollCapture() override; diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index b558fcb0b3179..a99a99d440b9e 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -1211,7 +1211,15 @@ struct ParamTraits mozilla::PanGestureInput::sHighestPanGestureType> {}; template <> -struct ParamTraits { +struct ParamTraits + : public ContiguousEnumSerializerInclusive< + mozilla::PanGestureInput::PanDeltaType, + mozilla::PanGestureInput::PanDeltaType::PANDELTA_PAGE, + mozilla::PanGestureInput::sHighestPanDeltaType> {}; + +template <> +struct ParamTraits + : BitfieldHelper { typedef mozilla::PanGestureInput paramType; static void Write(Message* aMsg, const paramType& aParam) { @@ -1225,6 +1233,7 @@ struct ParamTraits { WriteParam(aMsg, aParam.mLineOrPageDeltaY); WriteParam(aMsg, aParam.mUserDeltaMultiplierX); WriteParam(aMsg, aParam.mUserDeltaMultiplierY); + WriteParam(aMsg, aParam.mDeltaType); WriteParam(aMsg, aParam.mHandledByAPZ); WriteParam(aMsg, aParam.mFollowedByMomentum); WriteParam( @@ -1232,6 +1241,7 @@ struct ParamTraits { aParam .mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection); WriteParam(aMsg, aParam.mOverscrollBehaviorAllowsSwipe); + WriteParam(aMsg, aParam.mSimulateMomentum); } static bool Read(const Message* aMsg, PickleIterator* aIter, @@ -1246,13 +1256,19 @@ struct ParamTraits { ReadParam(aMsg, aIter, &aResult->mLineOrPageDeltaY) && ReadParam(aMsg, aIter, &aResult->mUserDeltaMultiplierX) && ReadParam(aMsg, aIter, &aResult->mUserDeltaMultiplierY) && - ReadParam(aMsg, aIter, &aResult->mHandledByAPZ) && - ReadParam(aMsg, aIter, &aResult->mFollowedByMomentum) && - ReadParam( - aMsg, aIter, - &aResult - ->mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection) && - ReadParam(aMsg, aIter, &aResult->mOverscrollBehaviorAllowsSwipe); + ReadParam(aMsg, aIter, &aResult->mDeltaType) && + ReadBoolForBitfield(aMsg, aIter, aResult, + ¶mType::SetHandledByAPZ) && + ReadBoolForBitfield(aMsg, aIter, aResult, + ¶mType::SetFollowedByMomentum) && + ReadBoolForBitfield( + aMsg, aIter, aResult, + ¶mType:: + SetRequiresContentResponseIfCannotScrollHorizontallyInStartDirection) && + ReadBoolForBitfield(aMsg, aIter, aResult, + ¶mType::SetOverscrollBehaviorAllowsSwipe) && + ReadBoolForBitfield(aMsg, aIter, aResult, + ¶mType::SetSimulateMomentum); } }; From 6f9598087bd9d8e9f0629147da2c6e57473da3e8 Mon Sep 17 00:00:00 2001 From: Cosmin Sabou Date: Fri, 21 Jun 2019 04:15:32 +0300 Subject: [PATCH 13/14] Bug 1560360 - Disable more flaky css-appearance tests on win7 debug and win10 aarch64. a=testonly --- .../web-platform/meta/css/css-ui/appearance-auto-001.html.ini | 1 + .../meta/css/css-ui/appearance-button-bevel-001.html.ini | 1 + .../meta/css/css-ui/appearance-checkbox-001.html.ini | 1 + .../meta/css/css-ui/appearance-listbox-001.html.ini | 1 + .../meta/css/css-ui/appearance-menulist-001.html.ini | 1 + .../meta/css/css-ui/appearance-menulist-button-001.html.ini | 1 + .../meta/css/css-ui/appearance-menulist-button-002.html.ini | 1 + .../web-platform/meta/css/css-ui/appearance-meter-001.html.ini | 1 + .../meta/css/css-ui/appearance-progress-bar-001.html.ini | 1 + .../meta/css/css-ui/appearance-push-button-001.html.ini | 1 + .../web-platform/meta/css/css-ui/appearance-radio-001.html.ini | 3 +++ .../meta/css/css-ui/appearance-searchfield-001.html.ini | 3 +++ .../meta/css/css-ui/appearance-slider-horizontal-001.html.ini | 2 ++ .../meta/css/css-ui/appearance-square-button-001.html.ini | 2 ++ .../meta/css/css-ui/appearance-textarea-001.html.ini | 2 ++ 15 files changed, 22 insertions(+) diff --git a/testing/web-platform/meta/css/css-ui/appearance-auto-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-auto-001.html.ini index 3e5bd9cd9313f..2bf394bcdec9a 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-auto-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-auto-001.html.ini @@ -3,3 +3,4 @@ if os == "win": FAIL disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 diff --git a/testing/web-platform/meta/css/css-ui/appearance-button-bevel-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-button-bevel-001.html.ini index 04bdcd1891fc2..7a154206a32d4 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-button-bevel-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-button-bevel-001.html.ini @@ -1,6 +1,7 @@ [appearance-button-bevel-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-checkbox-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-checkbox-001.html.ini index b3dad4a10f775..69748025999ec 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-checkbox-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-checkbox-001.html.ini @@ -3,3 +3,4 @@ if os == "win": FAIL disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 diff --git a/testing/web-platform/meta/css/css-ui/appearance-listbox-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-listbox-001.html.ini index f15fc865ffaba..5f522a6519605 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-listbox-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-listbox-001.html.ini @@ -3,3 +3,4 @@ if os == "win": FAIL disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 diff --git a/testing/web-platform/meta/css/css-ui/appearance-menulist-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-menulist-001.html.ini index 1d6091b45ccfe..e10576431cb9b 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-menulist-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-menulist-001.html.ini @@ -3,3 +3,4 @@ if os == "win": FAIL disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 diff --git a/testing/web-platform/meta/css/css-ui/appearance-menulist-button-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-menulist-button-001.html.ini index 860b95c6c30af..16e44eea5b890 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-menulist-button-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-menulist-button-001.html.ini @@ -1,6 +1,7 @@ [appearance-menulist-button-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-menulist-button-002.html.ini b/testing/web-platform/meta/css/css-ui/appearance-menulist-button-002.html.ini index 69bc63c2f64af..fc80f4ba10ab7 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-menulist-button-002.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-menulist-button-002.html.ini @@ -1,6 +1,7 @@ [appearance-menulist-button-002.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if os == "win": PASS FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-meter-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-meter-001.html.ini index 5b1a797b04aa5..93ea16ddb18c3 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-meter-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-meter-001.html.ini @@ -1,5 +1,6 @@ [appearance-meter-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if os == "win": FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-progress-bar-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-progress-bar-001.html.ini index 905cd84884029..7006660962914 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-progress-bar-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-progress-bar-001.html.ini @@ -1,5 +1,6 @@ [appearance-progress-bar-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if os == "win": FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-push-button-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-push-button-001.html.ini index b2d4d56dfa8b0..9778bfa799dcd 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-push-button-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-push-button-001.html.ini @@ -1,5 +1,6 @@ [appearance-push-button-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if os == "win": FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-radio-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-radio-001.html.ini index 75a53a6b4de13..5c237e59fdeb2 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-radio-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-radio-001.html.ini @@ -1,4 +1,7 @@ [appearance-radio-001.html] + disabled: + if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-searchfield-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-searchfield-001.html.ini index 919b7a7b0e528..0d6d14633d3b3 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-searchfield-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-searchfield-001.html.ini @@ -1,4 +1,7 @@ [appearance-searchfield-001.html] + disabled: + if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-slider-horizontal-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-slider-horizontal-001.html.ini index a8e46f6a67bc1..cf1fe893554e2 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-slider-horizontal-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-slider-horizontal-001.html.ini @@ -1,4 +1,6 @@ [appearance-slider-horizontal-001.html] + disabled: + if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-square-button-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-square-button-001.html.ini index 65f0c69945352..8ef54c0d09e7e 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-square-button-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-square-button-001.html.ini @@ -1,4 +1,6 @@ [appearance-square-button-001.html] + disabled: + if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-textarea-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-textarea-001.html.ini index 2b40d2c3f90dc..5f5e02a532d05 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-textarea-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-textarea-001.html.ini @@ -1,4 +1,6 @@ [appearance-textarea-001.html] + disabled: + if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL From 673d61dd1d70d5493488d5328e5309ecf5267f8d Mon Sep 17 00:00:00 2001 From: Cosmin Sabou Date: Fri, 21 Jun 2019 06:24:48 +0300 Subject: [PATCH 14/14] Bug 1560360 - Update syntax for disabling more flaky css-appearance tests on win7 debug and win10 aarch64. a=testonly --- .../web-platform/meta/css/css-ui/appearance-auto-001.html.ini | 2 +- .../meta/css/css-ui/appearance-button-bevel-001.html.ini | 2 +- .../meta/css/css-ui/appearance-checkbox-001.html.ini | 2 +- .../meta/css/css-ui/appearance-listbox-001.html.ini | 2 +- .../meta/css/css-ui/appearance-menulist-001.html.ini | 2 +- .../meta/css/css-ui/appearance-menulist-button-001.html.ini | 2 +- .../meta/css/css-ui/appearance-menulist-button-002.html.ini | 2 +- .../web-platform/meta/css/css-ui/appearance-meter-001.html.ini | 2 +- .../meta/css/css-ui/appearance-progress-bar-001.html.ini | 2 +- .../meta/css/css-ui/appearance-push-button-001.html.ini | 2 +- .../web-platform/meta/css/css-ui/appearance-radio-001.html.ini | 2 +- .../meta/css/css-ui/appearance-searchfield-001.html.ini | 2 +- .../meta/css/css-ui/appearance-slider-horizontal-001.html.ini | 1 + .../meta/css/css-ui/appearance-square-button-001.html.ini | 1 + .../meta/css/css-ui/appearance-textarea-001.html.ini | 1 + 15 files changed, 15 insertions(+), 12 deletions(-) diff --git a/testing/web-platform/meta/css/css-ui/appearance-auto-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-auto-001.html.ini index 2bf394bcdec9a..1139378eeb2b7 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-auto-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-auto-001.html.ini @@ -3,4 +3,4 @@ if os == "win": FAIL disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 - if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 diff --git a/testing/web-platform/meta/css/css-ui/appearance-button-bevel-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-button-bevel-001.html.ini index 7a154206a32d4..f928bcf8786d5 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-button-bevel-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-button-bevel-001.html.ini @@ -1,7 +1,7 @@ [appearance-button-bevel-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 - if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-checkbox-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-checkbox-001.html.ini index 69748025999ec..9a2701c62b788 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-checkbox-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-checkbox-001.html.ini @@ -3,4 +3,4 @@ if os == "win": FAIL disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 - if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 diff --git a/testing/web-platform/meta/css/css-ui/appearance-listbox-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-listbox-001.html.ini index 5f522a6519605..3c8392cda6885 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-listbox-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-listbox-001.html.ini @@ -3,4 +3,4 @@ if os == "win": FAIL disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 - if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 diff --git a/testing/web-platform/meta/css/css-ui/appearance-menulist-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-menulist-001.html.ini index e10576431cb9b..1270fef6badb4 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-menulist-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-menulist-001.html.ini @@ -3,4 +3,4 @@ if os == "win": FAIL disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 - if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 diff --git a/testing/web-platform/meta/css/css-ui/appearance-menulist-button-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-menulist-button-001.html.ini index 16e44eea5b890..006e354ff2f5f 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-menulist-button-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-menulist-button-001.html.ini @@ -1,7 +1,7 @@ [appearance-menulist-button-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 - if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-menulist-button-002.html.ini b/testing/web-platform/meta/css/css-ui/appearance-menulist-button-002.html.ini index fc80f4ba10ab7..1bc643469fa14 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-menulist-button-002.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-menulist-button-002.html.ini @@ -1,7 +1,7 @@ [appearance-menulist-button-002.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 - if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if os == "win": PASS FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-meter-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-meter-001.html.ini index 93ea16ddb18c3..d09dbfcf63e53 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-meter-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-meter-001.html.ini @@ -1,6 +1,6 @@ [appearance-meter-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 - if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if os == "win": FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-progress-bar-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-progress-bar-001.html.ini index 7006660962914..1328ccf058024 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-progress-bar-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-progress-bar-001.html.ini @@ -1,6 +1,6 @@ [appearance-progress-bar-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 - if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if os == "win": FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-push-button-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-push-button-001.html.ini index 9778bfa799dcd..338b2cdc45873 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-push-button-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-push-button-001.html.ini @@ -1,6 +1,6 @@ [appearance-push-button-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 - if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if os == "win": FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-radio-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-radio-001.html.ini index 5c237e59fdeb2..0987c3f5b6e2d 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-radio-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-radio-001.html.ini @@ -1,7 +1,7 @@ [appearance-radio-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 - if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-searchfield-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-searchfield-001.html.ini index 0d6d14633d3b3..0d4bf87a20ee4 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-searchfield-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-searchfield-001.html.ini @@ -1,7 +1,7 @@ [appearance-searchfield-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 - if os == "win" && processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-slider-horizontal-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-slider-horizontal-001.html.ini index cf1fe893554e2..4b11854c2501d 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-slider-horizontal-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-slider-horizontal-001.html.ini @@ -1,6 +1,7 @@ [appearance-slider-horizontal-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-square-button-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-square-button-001.html.ini index 8ef54c0d09e7e..c4c95cc24e892 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-square-button-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-square-button-001.html.ini @@ -1,6 +1,7 @@ [appearance-square-button-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL diff --git a/testing/web-platform/meta/css/css-ui/appearance-textarea-001.html.ini b/testing/web-platform/meta/css/css-ui/appearance-textarea-001.html.ini index 5f5e02a532d05..53ea79b556aaf 100644 --- a/testing/web-platform/meta/css/css-ui/appearance-textarea-001.html.ini +++ b/testing/web-platform/meta/css/css-ui/appearance-textarea-001.html.ini @@ -1,6 +1,7 @@ [appearance-textarea-001.html] disabled: if debug and os == "win" and version == "6.1.7601": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 + if os == "win" and processor == "aarch64": https://bugzilla.mozilla.org/show_bug.cgi?id=1560360 expected: if (os == "win") and debug and (processor == "x86_64"): FAIL if (os == "win") and not debug: FAIL