author | Carsten "Tomcat" Book <cbook@mozilla.com> |
Wed, 14 Sep 2016 15:45:49 +0200 | |
changeset 313897 | 4b1f411b1ea6e183a32c43bdd1ff672cca7fee6d |
parent 313879 | 109281cadd425161c50bce8ab4064faa68c4113c (current diff) |
parent 313896 | 8a494adbc5cced90a4edf0c98cffde906bf7f3ae (diff) |
child 313898 | 33de74be048e90b1ba1ca5ca8703d5ce176827c2 |
push id | 32267 |
push user | cbook@mozilla.com |
push date | Wed, 14 Sep 2016 13:46:59 +0000 |
treeherder | autoland@4b1f411b1ea6 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 51.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/accessible/base/TextAttrs.h +++ b/accessible/base/TextAttrs.h @@ -175,23 +175,23 @@ protected: virtual bool GetValueFor(Accessible* aAccessible, T* aValue) = 0; // Indicates if root value should be exposed. bool mGetRootValue; // Native value and flag indicating if the value is defined (initialized in // derived classes). Note, undefined native value means it is inherited // from root. - T mNativeValue; - bool mIsDefined; + MOZ_INIT_OUTSIDE_CTOR T mNativeValue; + MOZ_INIT_OUTSIDE_CTOR bool mIsDefined; // Native root value and flag indicating if the value is defined (initialized // in derived classes). - T mRootNativeValue; - bool mIsRootDefined; + MOZ_INIT_OUTSIDE_CTOR T mRootNativeValue; + MOZ_INIT_OUTSIDE_CTOR bool mIsRootDefined; }; /** * Class is used for the work with 'language' text attribute. */ class LangTextAttr : public TTextAttr<nsString> {
--- a/dom/base/nsXMLContentSerializer.h +++ b/dom/base/nsXMLContentSerializer.h @@ -331,42 +331,42 @@ class nsXMLContentSerializer : public ns nsString mPrefix; nsString mURI; nsIContent* mOwner; }; nsTArray<NameSpaceDecl> mNameSpaceStack; // nsIDocumentEncoder flags - uint32_t mFlags; + MOZ_INIT_OUTSIDE_CTOR uint32_t mFlags; // characters to use for line break nsString mLineBreak; // The charset that was passed to Init() nsCString mCharset; // current column position on the current line uint32_t mColPos; // true = pretty formating should be done (OutputFormated flag) - bool mDoFormat; + MOZ_INIT_OUTSIDE_CTOR bool mDoFormat; // true = no formatting,(OutputRaw flag) // no newline convertion and no rewrap long lines even if OutputWrap is set. - bool mDoRaw; + MOZ_INIT_OUTSIDE_CTOR bool mDoRaw; // true = wrapping should be done (OutputWrap flag) - bool mDoWrap; + MOZ_INIT_OUTSIDE_CTOR bool mDoWrap; // true = we can break lines (OutputDisallowLineBreaking flag) - bool mAllowLineBreaking; + MOZ_INIT_OUTSIDE_CTOR bool mAllowLineBreaking; // number of maximum column in a line, in the wrap mode - uint32_t mMaxColumn; + MOZ_INIT_OUTSIDE_CTOR uint32_t mMaxColumn; // current indent value nsString mIndent; // this is the indentation level after the indentation reached // the maximum length of indentation int32_t mIndentOverflow; @@ -392,15 +392,15 @@ class nsXMLContentSerializer : public ns // such character has already been added into the output string bool mMayIgnoreLineBreakSequence; bool mBodyOnly; int32_t mInBody; private: // number of nested elements which have preformated content - int32_t mPreLevel; + MOZ_INIT_OUTSIDE_CTOR int32_t mPreLevel; }; nsresult NS_NewXMLContentSerializer(nsIContentSerializer** aSerializer); #endif
--- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -2462,17 +2462,19 @@ CanvasRenderingContext2D::CreatePattern( HTMLImageElement* img = &aSource.GetAsHTMLImageElement(); if (img->IntrinsicState().HasState(NS_EVENT_STATE_BROKEN)) { aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return nullptr; } htmlElement = img; } else if (aSource.IsHTMLVideoElement()) { - htmlElement = &aSource.GetAsHTMLVideoElement(); + auto& video = aSource.GetAsHTMLVideoElement(); + video.MarkAsContentSource(mozilla::dom::HTMLVideoElement::CallerAPI::CREATE_PATTERN); + htmlElement = &video; } else { // Special case for ImageBitmap ImageBitmap& imgBitmap = aSource.GetAsImageBitmap(); EnsureTarget(); RefPtr<SourceSurface> srcSurf = imgBitmap.PrepareForDrawTarget(mTarget); if (!srcSurf) { JSContext* context = nsContentUtils::GetCurrentJSContext(); if (context) { @@ -4763,16 +4765,17 @@ CanvasRenderingContext2D::DrawImage(cons imgSize = gfx::IntSize(imageBitmap.Width(), imageBitmap.Height()); } else { if (aImage.IsHTMLImageElement()) { HTMLImageElement* img = &aImage.GetAsHTMLImageElement(); element = img; } else { HTMLVideoElement* video = &aImage.GetAsHTMLVideoElement(); + video->MarkAsContentSource(mozilla::dom::HTMLVideoElement::CallerAPI::DRAW_IMAGE); element = video; } srcSurf = CanvasImageCache::LookupCanvas(element, mCanvasElement, &imgSize, mIsSkiaGL); } nsLayoutUtils::DirectDrawInfo drawInfo;
--- a/dom/canvas/ImageBitmap.cpp +++ b/dom/canvas/ImageBitmap.cpp @@ -788,16 +788,18 @@ ImageBitmap::CreateInternal(nsIGlobalObj return ret.forget(); } /* static */ already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl, const Maybe<IntRect>& aCropRect, ErrorResult& aRv) { + aVideoEl.MarkAsContentSource(mozilla::dom::HTMLVideoElement::CallerAPI::CREATE_IMAGEBITMAP); + // Check network state. if (aVideoEl.NetworkState() == HTMLMediaElement::NETWORK_EMPTY) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return nullptr; } // Check ready state. // Cannot be HTMLMediaElement::HAVE_NOTHING or HTMLMediaElement::HAVE_METADATA.
--- a/dom/filesystem/GetFilesHelper.cpp +++ b/dom/filesystem/GetFilesHelper.cpp @@ -2,16 +2,17 @@ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "GetFilesHelper.h" #include "mozilla/dom/ContentChild.h" #include "mozilla/dom/ContentParent.h" +#include "nsProxyRelease.h" namespace mozilla { namespace dom { namespace { // This class is used in the DTOR of GetFilesHelper to release resources in the // correct thread. @@ -604,16 +605,21 @@ private: GetFilesHelperParent::GetFilesHelperParent(const nsID& aUUID, ContentParent* aContentParent, bool aRecursiveFlag) : GetFilesHelper(nullptr, aRecursiveFlag) , mContentParent(aContentParent) , mUUID(aUUID) {} +GetFilesHelperParent::~GetFilesHelperParent() +{ + NS_ReleaseOnMainThread(mContentParent.forget()); +} + /* static */ already_AddRefed<GetFilesHelperParent> GetFilesHelperParent::Create(const nsID& aUUID, const nsAString& aDirectoryPath, bool aRecursiveFlag, ContentParent* aContentParent, ErrorResult& aRv) { MOZ_ASSERT(aContentParent); RefPtr<GetFilesHelperParent> helper =
--- a/dom/filesystem/GetFilesHelper.h +++ b/dom/filesystem/GetFilesHelper.h @@ -193,16 +193,18 @@ public: static already_AddRefed<GetFilesHelperParent> Create(const nsID& aUUID, const nsAString& aDirectoryPath, bool aRecursiveFlag, ContentParent* aContentParent, ErrorResult& aRv); private: GetFilesHelperParent(const nsID& aUUID, ContentParent* aContentParent, bool aRecursiveFlag); + ~GetFilesHelperParent(); + RefPtr<ContentParent> mContentParent; nsID mUUID; }; } // dom namespace } // mozilla namespace #endif // mozilla_dom_GetFilesHelper_h
--- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -2541,16 +2541,18 @@ HTMLMediaElement::AddCaptureMediaTrackTo already_AddRefed<DOMMediaStream> HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded, bool aCaptureAudio, MediaStreamGraph* aGraph) { MOZ_RELEASE_ASSERT(aGraph); + MarkAsContentSource(CallerAPI::CAPTURE_STREAM); + nsPIDOMWindowInner* window = OwnerDoc()->GetInnerWindow(); if (!window) { return nullptr; } #ifdef MOZ_EME if (ContainsRestrictedContent()) { return nullptr; } @@ -2920,17 +2922,18 @@ HTMLMediaElement::HTMLMediaElement(alrea mAudioChannelVolume(1.0), mPlayingThroughTheAudioChannel(false), mDisableVideo(false), mElementInTreeState(ELEMENT_NOT_INTREE), mHasUserInteraction(false), mFirstFrameLoaded(false), mDefaultPlaybackStartPosition(0.0), mIsAudioTrackAudible(false), - mAudible(IsAudible()) + mAudible(IsAudible()), + mVisibilityState(Visibility::APPROXIMATELY_NONVISIBLE) { ErrorResult rv; double defaultVolume = Preferences::GetFloat("media.default_volume", 1.0); SetVolume(defaultVolume, rv); mAudioChannel = AudioChannelService::GetDefaultAudioChannel(); @@ -6039,16 +6042,18 @@ static const char* VisibilityString(Visi } void HTMLMediaElement::OnVisibilityChange(Visibility aNewVisibility) { LOG(LogLevel::Debug, ("OnVisibilityChange(): %s\n", VisibilityString(aNewVisibility))); + mVisibilityState = aNewVisibility; + if (!mDecoder) { return; } switch (aNewVisibility) { case Visibility::UNTRACKED: { MOZ_ASSERT_UNREACHABLE("Shouldn't notify for untracked visibility"); break; @@ -6589,10 +6594,71 @@ HTMLMediaElement::NotifyCueDisplayStates { if (!mTextTrackManager) { return; } mTextTrackManager->DispatchUpdateCueDisplay(); } +void +HTMLMediaElement::MarkAsContentSource(CallerAPI aAPI) +{ + const bool isVisible = mVisibilityState != Visibility::APPROXIMATELY_NONVISIBLE; + + if (isVisible) { + // 0 = ALL_VISIBLE + Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 0); + } else { + // 1 = ALL_INVISIBLE + Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 1); + } + + switch (aAPI) { + case CallerAPI::DRAW_IMAGE: { + if (isVisible) { + // 2 = drawImage_VISIBLE + Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 2); + } else { + // 3 = drawImage_INVISIBLE + Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 3); + } + break; + } + case CallerAPI::CREATE_PATTERN: { + if (isVisible) { + // 4 = createPattern_VISIBLE + Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 4); + } else { + // 5 = createPattern_INVISIBLE + Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 5); + } + break; + } + case CallerAPI::CREATE_IMAGEBITMAP: { + if (isVisible) { + // 6 = createImageBitmap_VISIBLE + Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 6); + } else { + // 7 = createImageBitmap_INVISIBLE + Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 7); + } + break; + } + case CallerAPI::CAPTURE_STREAM: { + if (isVisible) { + // 8 = captureStream_VISIBLE + Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 8); + } else { + // 9 = captureStream_INVISIBLE + Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 9); + } + break; + } + } + + LOG(LogLevel::Debug, + ("%p Log VIDEO_AS_CONTENT_SOURCE: visibility = %u, API: '%d' and 'All'", + this, isVisible, aAPI)); +} + } // namespace dom } // namespace mozilla
--- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -734,16 +734,27 @@ public: // These are used for testing only float ComputedVolume() const; bool ComputedMuted() const; nsSuspendedTypes ComputedSuspended() const; void SetMediaInfo(const MediaInfo& aInfo); + // Telemetry: to record the usage of a {visible / invisible} video element as + // the source of {drawImage(), createPattern(), createImageBitmap() and + // captureStream()} APIs. + enum class CallerAPI { + DRAW_IMAGE, + CREATE_PATTERN, + CREATE_IMAGEBITMAP, + CAPTURE_STREAM, + }; + void MarkAsContentSource(CallerAPI aAPI); + protected: virtual ~HTMLMediaElement(); class ChannelLoader; class MediaLoadListener; class MediaStreamTracksAvailableCallback; class MediaStreamTrackListener; class StreamListener; @@ -1710,14 +1721,16 @@ private: // be seeked even before the media is loaded. double mDefaultPlaybackStartPosition; // True if the audio track is not silent. bool mIsAudioTrackAudible; // True if media element is audible for users. bool mAudible; + + Visibility mVisibilityState; }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_HTMLMediaElement_h
--- a/dom/xul/templates/nsXULSortService.h +++ b/dom/xul/templates/nsXULSortService.h @@ -37,33 +37,34 @@ enum nsSortState_direction { nsSortState_ascending, nsSortState_natural }; // the sort state holds info about the current sort struct nsSortState { bool initialized; - bool invertSort; - bool inbetweenSeparatorSort; - bool sortStaticsLast; - bool isContainerRDFSeq; + MOZ_INIT_OUTSIDE_CTOR bool invertSort; + MOZ_INIT_OUTSIDE_CTOR bool inbetweenSeparatorSort; + MOZ_INIT_OUTSIDE_CTOR bool sortStaticsLast; + MOZ_INIT_OUTSIDE_CTOR bool isContainerRDFSeq; uint32_t sortHints; - nsSortState_direction direction; + MOZ_INIT_OUTSIDE_CTOR nsSortState_direction direction; nsAutoString sort; nsCOMArray<nsIAtom> sortKeys; nsCOMPtr<nsIXULTemplateQueryProcessor> processor; nsCOMPtr<nsIContent> lastContainer; - bool lastWasFirst, lastWasLast; + MOZ_INIT_OUTSIDE_CTOR bool lastWasFirst, lastWasLast; nsSortState() : initialized(false), + isContainerRDFSeq(false), sortHints(0) { } void Traverse(nsCycleCollectionTraversalCallback &cb) const { cb.NoteXPCOMChild(processor); cb.NoteXPCOMChild(lastContainer); }
--- a/gfx/gl/GLScreenBuffer.cpp +++ b/gfx/gl/GLScreenBuffer.cpp @@ -946,21 +946,21 @@ ReadBuffer::Create(GLContext* gl, GLenum err = localError.GetError(); MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_OUT_OF_MEMORY); if (err) return nullptr; const bool needsAcquire = !surf->IsProducerAcquired(); if (needsAcquire) { - surf->ProducerAcquire(); + surf->ProducerReadAcquire(); } const bool isComplete = gl->IsFramebufferComplete(fb); if (needsAcquire) { - surf->ProducerRelease(); + surf->ProducerReadRelease(); } if (!isComplete) return nullptr; return Move(ret); }
--- a/js/src/asmjs/WasmBinary.h +++ b/js/src/asmjs/WasmBinary.h @@ -19,16 +19,24 @@ #ifndef wasm_binary_h #define wasm_binary_h #include "builtin/SIMD.h" namespace js { namespace wasm { +// Telemetry sample values for the JS_AOT_USAGE key, indicating whether asm.js +// or WebAssembly is used. + +enum class Telemetry { + ASMJS = 0, + WASM = 1 +}; + static const uint32_t MagicNumber = 0x6d736100; // "\0asm" static const uint32_t EncodingVersion = 0x0b; static const char TypeSectionId[] = "type"; static const char GlobalSectionId[] = "global"; static const char ImportSectionId[] = "import"; static const char FunctionSectionId[] = "function"; static const char TableSectionId[] = "table";
--- a/js/src/asmjs/WasmCompile.h +++ b/js/src/asmjs/WasmCompile.h @@ -35,17 +35,17 @@ struct ScriptedCaller }; // Describes all the parameters that control wasm compilation. struct CompileArgs { Assumptions assumptions; ScriptedCaller scriptedCaller; - bool alwaysBaseline; + MOZ_INIT_OUTSIDE_CTOR bool alwaysBaseline; CompileArgs(Assumptions&& assumptions, ScriptedCaller&& scriptedCaller) : assumptions(Move(assumptions)), scriptedCaller(Move(scriptedCaller)), alwaysBaseline(false) {} // If CompileArgs is constructed without arguments, initFromContext() must
--- a/js/src/asmjs/WasmModule.cpp +++ b/js/src/asmjs/WasmModule.cpp @@ -865,10 +865,13 @@ Module::instantiate(JSContext* cx, return false; } else { uint32_t funcDefIndex = startFuncIndex - funcImports.length(); if (!instance->instance().callExport(cx, funcDefIndex, args)) return false; } } + uint32_t mode = uint32_t(metadata().isAsmJS() ? Telemetry::ASMJS : Telemetry::WASM); + cx->runtime()->addTelemetry(JS_TELEMETRY_AOT_USAGE, mode); + return true; }
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/ion/for-in-iterator-1.js @@ -0,0 +1,28 @@ +var values = { + input1: null, + input2: undefined, + input3: {}, + input4: [], + input5: "" +}; + +var original = function (x) { + var res = { start: inIon(), end: false }; + for (var i in x.input) { + throw "Iterator is not empty"; + } + res.end = inIon(); + return res; +}; + +for (var i = 1; i < 6; i++) { + // Reset type inference. + var res = false; + var test = eval(original.toSource().replace(".input", ".input" + i)); + + // Run until the end is running within Ion, or skip if we are unable to run + // in Ion. + while (!res.start) + res = test(values); + assertEq(!res.start || !res.end, false); +}
--- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -7585,17 +7585,21 @@ static bool DoIteratorNewFallback(JSContext* cx, BaselineFrame* frame, ICIteratorNew_Fallback* stub, HandleValue value, MutableHandleValue res) { jsbytecode* pc = stub->icEntry()->pc(frame->script()); FallbackICSpew(cx, stub, "IteratorNew"); uint8_t flags = GET_UINT8(pc); res.set(value); - return ValueToIterator(cx, flags, res); + RootedObject iterobj(cx, ValueToIterator(cx, flags, res)); + if (!iterobj) + return false; + res.setObject(*iterobj); + return true; } typedef bool (*DoIteratorNewFallbackFn)(JSContext*, BaselineFrame*, ICIteratorNew_Fallback*, HandleValue, MutableHandleValue); static const VMFunction DoIteratorNewFallbackInfo = FunctionInfo<DoIteratorNewFallbackFn>(DoIteratorNewFallback, "DoIteratorNewFallback", TailCall, PopValues(1));
--- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -8734,22 +8734,34 @@ void CodeGenerator::visitArrayJoin(LArrayJoin* lir) { pushArg(ToRegister(lir->separator())); pushArg(ToRegister(lir->array())); callVM(ArrayJoinInfo, lir); } +typedef JSObject* (*ValueToIteratorFn)(JSContext*, uint32_t, HandleValue); +static const VMFunction ValueToIteratorInfo = + FunctionInfo<ValueToIteratorFn>(ValueToIterator, "ValueToIterator"); + +void +CodeGenerator::visitCallIteratorStartV(LCallIteratorStartV* lir) +{ + pushArg(ToValue(lir, LCallIteratorStartV::Value)); + pushArg(Imm32(lir->mir()->flags())); + callVM(ValueToIteratorInfo, lir); +} + typedef JSObject* (*GetIteratorObjectFn)(JSContext*, HandleObject, uint32_t); static const VMFunction GetIteratorObjectInfo = FunctionInfo<GetIteratorObjectFn>(GetIteratorObject, "GetIteratorObject"); void -CodeGenerator::visitCallIteratorStart(LCallIteratorStart* lir) +CodeGenerator::visitCallIteratorStartO(LCallIteratorStartO* lir) { pushArg(Imm32(lir->mir()->flags())); pushArg(ToRegister(lir->object())); callVM(GetIteratorObjectInfo, lir); } void CodeGenerator::branchIfNotEmptyObjectElements(Register obj, Label* target) @@ -8762,17 +8774,17 @@ CodeGenerator::branchIfNotEmptyObjectEle masm.branchPtr(Assembler::NotEqual, Address(obj, NativeObject::offsetOfElements()), ImmPtr(js::emptyObjectElementsShared), target); masm.bind(&emptyObj); } void -CodeGenerator::visitIteratorStart(LIteratorStart* lir) +CodeGenerator::visitIteratorStartO(LIteratorStartO* lir) { const Register obj = ToRegister(lir->object()); const Register output = ToRegister(lir->output()); uint32_t flags = lir->mir()->flags(); OutOfLineCode* ool = oolCallVM(GetIteratorObjectInfo, lir, ArgList(obj, Imm32(flags)), StoreRegisterTo(output));
--- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -320,18 +320,19 @@ class CodeGenerator final : public CodeG void visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole* lir); void visitStoreUnboxedScalar(LStoreUnboxedScalar* lir); void visitStoreTypedArrayElementHole(LStoreTypedArrayElementHole* lir); void visitAtomicIsLockFree(LAtomicIsLockFree* lir); void visitGuardSharedTypedArray(LGuardSharedTypedArray* lir); void visitClampIToUint8(LClampIToUint8* lir); void visitClampDToUint8(LClampDToUint8* lir); void visitClampVToUint8(LClampVToUint8* lir); - void visitCallIteratorStart(LCallIteratorStart* lir); - void visitIteratorStart(LIteratorStart* lir); + void visitCallIteratorStartV(LCallIteratorStartV* lir); + void visitCallIteratorStartO(LCallIteratorStartO* lir); + void visitIteratorStartO(LIteratorStartO* lir); void visitIteratorMore(LIteratorMore* lir); void visitIsNoIterAndBranch(LIsNoIterAndBranch* lir); void visitIteratorEnd(LIteratorEnd* lir); void visitArgumentsLength(LArgumentsLength* lir); void visitGetFrameArgument(LGetFrameArgument* lir); void visitSetFrameArgumentT(LSetFrameArgumentT* lir); void visitSetFrameArgumentC(LSetFrameArgumentC* lir); void visitSetFrameArgumentV(LSetFrameArgumentV* lir);
--- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -3901,23 +3901,32 @@ LIRGenerator::visitCallInitElementArray( useBoxAtStart(ins->value())); add(lir, ins); assignSafepoint(lir, ins); } void LIRGenerator::visitIteratorStart(MIteratorStart* ins) { + if (ins->object()->type() == MIRType::Value) { + LCallIteratorStartV* lir = new(alloc()) LCallIteratorStartV(useBoxAtStart(ins->object())); + defineReturn(lir, ins); + assignSafepoint(lir, ins); + return; + } + + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + // Call a stub if this is not a simple for-in loop. if (ins->flags() != JSITER_ENUMERATE) { - LCallIteratorStart* lir = new(alloc()) LCallIteratorStart(useRegisterAtStart(ins->object())); + LCallIteratorStartO* lir = new(alloc()) LCallIteratorStartO(useRegisterAtStart(ins->object())); defineReturn(lir, ins); assignSafepoint(lir, ins); } else { - LIteratorStart* lir = new(alloc()) LIteratorStart(useRegister(ins->object()), temp(), temp(), temp()); + LIteratorStartO* lir = new(alloc()) LIteratorStartO(useRegister(ins->object()), temp(), temp(), temp()); define(lir, ins); assignSafepoint(lir, ins); } } void LIRGenerator::visitIteratorMore(MIteratorMore* ins) {
--- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -11961,17 +11961,17 @@ class MRound return true; } ALLOW_CLONE(MRound) }; class MIteratorStart : public MUnaryInstruction, - public SingleObjectPolicy::Data + public BoxExceptPolicy<0, MIRType::Object>::Data { uint8_t flags_; MIteratorStart(MDefinition* obj, uint8_t flags) : MUnaryInstruction(obj), flags_(flags) { setResultType(MIRType::Object); }
--- a/js/src/jit/TypePolicy.cpp +++ b/js/src/jit/TypePolicy.cpp @@ -641,21 +641,17 @@ bool BoxExceptPolicy<Op, Type>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins) { MDefinition* in = ins->getOperand(Op); if (in->type() == Type) return true; return BoxPolicy<Op>::staticAdjustInputs(alloc, ins); } -template bool BoxExceptPolicy<0, MIRType::String>::staticAdjustInputs(TempAllocator& alloc, - MInstruction* ins); -template bool BoxExceptPolicy<1, MIRType::String>::staticAdjustInputs(TempAllocator& alloc, - MInstruction* ins); -template bool BoxExceptPolicy<2, MIRType::String>::staticAdjustInputs(TempAllocator& alloc, +template bool BoxExceptPolicy<0, MIRType::Object>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins); template <unsigned Op> bool CacheIdPolicy<Op>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins) { MDefinition* in = ins->getOperand(Op); switch (in->type()) { @@ -1207,17 +1203,17 @@ FilterTypeSetPolicy::adjustInputs(TempAl _(TestPolicy) \ _(AllDoublePolicy) \ _(ToDoublePolicy) \ _(ToInt32Policy) \ _(ToStringPolicy) \ _(TypeBarrierPolicy) #define TEMPLATE_TYPE_POLICY_LIST(_) \ - _(BoxExceptPolicy<0, MIRType::String>) \ + _(BoxExceptPolicy<0, MIRType::Object>) \ _(BoxPolicy<0>) \ _(ConvertToInt32Policy<0>) \ _(ConvertToStringPolicy<0>) \ _(ConvertToStringPolicy<2>) \ _(DoublePolicy<0>) \ _(FloatingPointPolicy<0>) \ _(IntPolicy<0>) \ _(IntPolicy<1>) \
--- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -7090,39 +7090,54 @@ class LSetPropertyCache : public LInstru } const LDefinition* tempFloat32() { if (hasUnaliasedDouble()) return getTemp(3); return getTemp(2); } }; -class LCallIteratorStart : public LCallInstructionHelper<1, 1, 0> -{ - public: - LIR_HEADER(CallIteratorStart) - - explicit LCallIteratorStart(const LAllocation& object) { +class LCallIteratorStartV : public LCallInstructionHelper<1, BOX_PIECES, 0> +{ + public: + LIR_HEADER(CallIteratorStartV) + + static const size_t Value = 0; + + explicit LCallIteratorStartV(const LBoxAllocation& value) { + setBoxOperand(Value, value); + } + MIteratorStart* mir() const { + return mir_->toIteratorStart(); + } +}; + +class LCallIteratorStartO : public LCallInstructionHelper<1, 1, 0> +{ + public: + LIR_HEADER(CallIteratorStartO) + + explicit LCallIteratorStartO(const LAllocation& object) { setOperand(0, object); } const LAllocation* object() { return getOperand(0); } MIteratorStart* mir() const { return mir_->toIteratorStart(); } }; -class LIteratorStart : public LInstructionHelper<1, 1, 3> -{ - public: - LIR_HEADER(IteratorStart) - - LIteratorStart(const LAllocation& object, const LDefinition& temp1, - const LDefinition& temp2, const LDefinition& temp3) { +class LIteratorStartO : public LInstructionHelper<1, 1, 3> +{ + public: + LIR_HEADER(IteratorStartO) + + LIteratorStartO(const LAllocation& object, const LDefinition& temp1, + const LDefinition& temp2, const LDefinition& temp3) { setOperand(0, object); setTemp(0, temp1); setTemp(1, temp2); setTemp(2, temp3); } const LAllocation* object() { return getOperand(0); }
--- a/js/src/jit/shared/LOpcodes-shared.h +++ b/js/src/jit/shared/LOpcodes-shared.h @@ -329,18 +329,19 @@ _(CallSetElement) \ _(CallInitElementArray) \ _(CallSetProperty) \ _(CallDeleteProperty) \ _(CallDeleteElement) \ _(SetPropertyCache) \ _(SetPropertyPolymorphicV) \ _(SetPropertyPolymorphicT) \ - _(CallIteratorStart) \ - _(IteratorStart) \ + _(CallIteratorStartV) \ + _(CallIteratorStartO) \ + _(IteratorStartO) \ _(IteratorMore) \ _(IsNoIterAndBranch) \ _(IteratorEnd) \ _(ArrayLength) \ _(SetArrayLength) \ _(GetNextMapEntryForIterator) \ _(TypedArrayLength) \ _(TypedArrayElements) \
--- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -128,16 +128,17 @@ enum { JS_TELEMETRY_GC_MINOR_REASON, JS_TELEMETRY_GC_MINOR_REASON_LONG, JS_TELEMETRY_GC_MINOR_US, JS_TELEMETRY_GC_NURSERY_BYTES, JS_TELEMETRY_GC_PRETENURE_COUNT, JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_ADDONS, JS_TELEMETRY_ADDON_EXCEPTIONS, + JS_TELEMETRY_AOT_USAGE, JS_TELEMETRY_END }; typedef void (*JSAccumulateTelemetryDataCallback)(int id, uint32_t sample, const char* key); extern JS_FRIEND_API(void) JS_SetAccumulateTelemetryCallback(JSContext* cx, JSAccumulateTelemetryDataCallback callback);
--- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -996,19 +996,20 @@ js::IteratorConstructor(JSContext* cx, u return false; } bool keyonly = false; if (args.length() >= 2) keyonly = ToBoolean(args[1]); unsigned flags = JSITER_OWNONLY | (keyonly ? 0 : (JSITER_FOREACH | JSITER_KEYVALUE)); - if (!ValueToIterator(cx, flags, args[0])) + RootedObject iterobj(cx, ValueToIterator(cx, flags, args[0])); + if (!iterobj) return false; - args.rval().set(args[0]); + args.rval().setObject(*iterobj); return true; } MOZ_ALWAYS_INLINE bool NativeIteratorNext(JSContext* cx, NativeIterator* ni, MutableHandleValue rval, bool* done) { *done = false; @@ -1174,48 +1175,46 @@ enum { ListIteratorSlotCount }; const Class ListIteratorObject::class_ = { "List Iterator", JSCLASS_HAS_RESERVED_SLOTS(ListIteratorSlotCount) }; -bool -js::ValueToIterator(JSContext* cx, unsigned flags, MutableHandleValue vp) +JSObject* +js::ValueToIterator(JSContext* cx, unsigned flags, HandleValue vp) { /* JSITER_KEYVALUE must always come with JSITER_FOREACH */ MOZ_ASSERT_IF(flags & JSITER_KEYVALUE, flags & JSITER_FOREACH); RootedObject obj(cx); if (vp.isObject()) { /* Common case. */ obj = &vp.toObject(); } else if ((flags & JSITER_ENUMERATE) && vp.isNullOrUndefined()) { /* * Enumerating over null and undefined gives an empty enumerator, so * that |for (var p in <null or undefined>) <loop>;| never executes * <loop>, per ES5 12.6.4. */ RootedObject iter(cx); if (!NewEmptyPropertyIterator(cx, flags, &iter)) - return false; - vp.setObject(*iter); - return true; + return nullptr; + return iter; } else { obj = ToObject(cx, vp); if (!obj) - return false; + return nullptr; } RootedObject iter(cx); if (!GetIterator(cx, obj, flags, &iter)) - return false; - vp.setObject(*iter); - return true; + return nullptr; + return iter; } bool js::CloseIterator(JSContext* cx, HandleObject obj) { if (obj->is<PropertyIteratorObject>()) { /* Remove enumerators from the active list, which is a stack. */ NativeIterator* ni = obj->as<PropertyIteratorObject>().getNativeIterator();
--- a/js/src/jsiter.h +++ b/js/src/jsiter.h @@ -175,18 +175,18 @@ bool NewEmptyPropertyIterator(JSContext* cx, unsigned flags, MutableHandleObject objp); /* * Convert the value stored in *vp to its iteration object. The flags should * contain JSITER_ENUMERATE if js::ValueToIterator is called when enumerating * for-in semantics are required, and when the caller can guarantee that the * iterator will never be exposed to scripts. */ -bool -ValueToIterator(JSContext* cx, unsigned flags, MutableHandleValue vp); +JSObject* +ValueToIterator(JSContext* cx, unsigned flags, HandleValue vp); bool CloseIterator(JSContext* cx, HandleObject iterObj); bool UnwindIteratorForException(JSContext* cx, HandleObject obj); void
--- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -2119,20 +2119,22 @@ CASE(JSOP_IN) REGS.sp[-1].setBoolean(found); } END_CASE(JSOP_IN) CASE(JSOP_ITER) { MOZ_ASSERT(REGS.stackDepth() >= 1); uint8_t flags = GET_UINT8(REGS.pc); - MutableHandleValue res = REGS.stackHandleAt(-1); - if (!ValueToIterator(cx, flags, res)) + HandleValue val = REGS.stackHandleAt(-1); + ReservedRooted<JSObject*> iter(&rootObject0); + iter.set(ValueToIterator(cx, flags, val)); + if (!iter) goto error; - MOZ_ASSERT(res.isObject()); + REGS.sp[-1].setObject(*iter); } END_CASE(JSOP_ITER) CASE(JSOP_MOREITER) { MOZ_ASSERT(REGS.stackDepth() >= 1); MOZ_ASSERT(REGS.sp[-1].isObject()); PUSH_NULL();
--- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -3154,16 +3154,19 @@ AccumulateTelemetryCallback(int id, uint Telemetry::Accumulate(Telemetry::JS_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, sample); break; case JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_ADDONS: Telemetry::Accumulate(Telemetry::JS_DEPRECATED_LANGUAGE_EXTENSIONS_IN_ADDONS, sample); break; case JS_TELEMETRY_ADDON_EXCEPTIONS: Telemetry::Accumulate(Telemetry::JS_TELEMETRY_ADDON_EXCEPTIONS, nsDependentCString(key), sample); break; + case JS_TELEMETRY_AOT_USAGE: + Telemetry::Accumulate(Telemetry::JS_AOT_USAGE, sample); + break; default: MOZ_ASSERT_UNREACHABLE("Unexpected JS_TELEMETRY id"); } } static void CompartmentNameCallback(JSContext* cx, JSCompartment* comp, char* buf, size_t bufsize)
--- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -942,17 +942,17 @@ GetScrollableOverflowForPerspective(nsIF overhang.top /= bottomDelta; overhang.right /= rightDelta; overhang.bottom /= bottomDelta; overhang.left /= rightDelta; // Take the minimum overflow rect that would allow the current scroll // position, using the size of the scroll port and offset by the // inverse of the scroll position. - nsRect overflow(0, 0, aScrollPort.width, aScrollPort.height); + nsRect overflow = aScrollPort - scrollPos; // Expand it by our margins to get an overflow rect that would allow all // edges of our transformed content to be scrolled into view. overflow.Inflate(overhang); // Merge it with the combined overflow aScrolledFrameOverflowArea.UnionRect(aScrolledFrameOverflowArea, overflow);
--- a/layout/generic/test/test_bug1198135.html +++ b/layout/generic/test/test_bug1198135.html @@ -72,13 +72,18 @@ https://bugzilla.mozilla.org/show_bug.cg <div class="example__group"> <div class="example__layer layer--c"></div> <div class="example__layer layer--e"></div> </div> </div> <script> is(document.getElementById("first").scrollHeight, 600, "Scroll height should be computed correctly"); + document.getElementById("first").scrollTop = 150; + is(document.getElementById("first").scrollHeight, 600, "Scroll height should be a constant when scrolling"); + // The true height is 727.5 and we don't always snap the same direction. isfuzzy(document.getElementById("second").scrollHeight, 728, 1, "Scroll height should be computed correctly"); + document.getElementById("second").scrollTop = 150; + isfuzzy(document.getElementById("second").scrollHeight, 728, 1, "Scroll height should be a constant when scrolling"); </script> </body></html>
--- a/layout/svg/SVGContextPaint.h +++ b/layout/svg/SVGContextPaint.h @@ -77,19 +77,20 @@ public: return mDashOffset; } gfxFloat GetStrokeWidth() { return mStrokeWidth; } private: + // Member-vars are initialized in InitStrokeGeometry. FallibleTArray<gfxFloat> mDashes; - gfxFloat mDashOffset; - gfxFloat mStrokeWidth; + MOZ_INIT_OUTSIDE_CTOR gfxFloat mDashOffset; + MOZ_INIT_OUTSIDE_CTOR gfxFloat mStrokeWidth; }; /** * RAII class used to temporarily set and remove an SVGContextPaint while a * piece of SVG is being painted. The context paint is set on the SVG's owner * document, as expected by SVGContextPaint::GetContextPaint. Any pre-existing * context paint is restored after this class removes the context paint that it * set. @@ -162,17 +163,18 @@ public: } union { nsSVGPaintServerFrame* mPaintServerFrame; SVGContextPaint* mContextPaint; nscolor mColor; } mPaintDefinition; - nsIFrame* mFrame; + // Initialized (if needed) in SetPaintServer(): + MOZ_INIT_OUTSIDE_CTOR nsIFrame* mFrame; // CTM defining the user space for the pattern we will use. gfxMatrix mContextMatrix; nsStyleSVGPaintType mPaintType; // Device-space-to-pattern-space gfxMatrix mPatternMatrix; nsRefPtrHashtable<nsFloatHashKey, gfxPattern> mPatternCache;
--- a/netwerk/protocol/http/AlternateServices.h +++ b/netwerk/protocol/http/AlternateServices.h @@ -100,31 +100,31 @@ private: RefPtr<DataStorage> mStorage; int32_t mStorageEpoch; void Serialize (nsCString &out); nsCString mHashKey; // If you change any of these members, update Serialize() nsCString mAlternateHost; - int32_t mAlternatePort; + MOZ_INIT_OUTSIDE_CTOR int32_t mAlternatePort; nsCString mOriginHost; - int32_t mOriginPort; + MOZ_INIT_OUTSIDE_CTOR int32_t mOriginPort; nsCString mUsername; - bool mPrivate; + MOZ_INIT_OUTSIDE_CTOR bool mPrivate; - uint32_t mExpiresAt; // alt-svc mappping + MOZ_INIT_OUTSIDE_CTOR uint32_t mExpiresAt; // alt-svc mappping - bool mValidated; - bool mHttps; // origin is https:// - bool mMixedScheme; // .wk allows http and https on same con + MOZ_INIT_OUTSIDE_CTOR bool mValidated; + MOZ_INIT_OUTSIDE_CTOR bool mHttps; // origin is https:// + MOZ_INIT_OUTSIDE_CTOR bool mMixedScheme; // .wk allows http and https on same con - nsCString mNPNToken; + nsCString mNPNToken; }; class AltSvcOverride : public nsIInterfaceRequestor , public nsISpeculativeConnectionOverrider { public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSISPECULATIVECONNECTIONOVERRIDER
--- a/testing/web-platform/meta/encrypted-media/__dir__.ini +++ b/testing/web-platform/meta/encrypted-media/__dir__.ini @@ -1,2 +1,2 @@ disabled: - if os == "linux": https://bugzilla.mozilla.org/show_bug.cgi?id=1301418 \ No newline at end of file + if (os == "linux") or (os == "mac"): https://bugzilla.mozilla.org/show_bug.cgi?id=1301418 \ No newline at end of file
--- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -8554,16 +8554,24 @@ "expires_in_version": "55", "description": "Time taken for a video to resume after decoding was suspended, in milliseconds. Keyed by audio presence, hw acceleration, and by height ranges (boundaries: 240. 480, 720, 1080, 2160), e.g.: 'V,0-240', 'AV(hw),2160+'; and 'All' will accumulate all percentages.", "keyed": true, "kind": "exponential", "high": 10000, "n_buckets": 100, "bug_numbers": [1294349] }, + "VIDEO_AS_CONTENT_SOURCE" : { + "alert_emails": ["ajones@mozilla.com", "kaku@mozilla.com"], + "expires_in_version": "56", + "description": "Usage of a {visible / invisible} video element as the source of {drawImage(), createPattern(), createImageBitmap() and captureStream()} APIs. (0 = ALL_VISIBLE, 1 = ALL_INVISIBLE, 2 = drawImage_VISIBLE, 3 = drawImage_INVISIBLE, 4 = createPattern_VISIBLE, 5 = createPattern_INVISIBLE, 6 = createImageBitmap_VISIBLE, 7 = createImageBitmap_INVISIBLE, 8 = captureStream_VISIBLE, 9 = captureStream_INVISIBLE)", + "kind": "enumerated", + "n_values": 12, + "bug_numbers": [1299718] + }, "VIDEO_UNLOAD_STATE": { "alert_emails": ["ajones@mozilla.com"], "expires_in_version": "55", "kind": "enumerated", "n_values": 5, "description": "HTML Media Element state when unloading. ended = 0, paused = 1, stalled = 2, seeking = 3, other = 4", "bug_numbers": [1261955, 1261955] }, @@ -10302,10 +10310,18 @@ "WEB_PERMISSION_CLEARED": { "alert_emails": ["firefox-dev@mozilla.org"], "bug_numbers": [1286118], "expires_in_version": "55", "kind": "enumerated", "keyed": true, "n_values": 6, "description": "Number of revoke actions on permissions in the control center, keyed by permission id. Values represent the permission type that was revoked. (0=unknown, 1=permanently allowed, 2=permanently blocked, 3=temporarily allowed, 4=temporarily blocked)" + }, + "JS_AOT_USAGE": { + "alert_emails": ["luke@mozilla.com", "bbouvier@mozilla.com"], + "bug_numbers": [1288778], + "expires_in_version": "56", + "kind": "enumerated", + "n_values": 4, + "description": "Counts the number of asm.js vs WebAssembly modules instanciations, at the time modules are getting instanciated." } }