From 51def7fb136f090502c822b81efc1075c1312083 Mon Sep 17 00:00:00 2001 From: Brian Hackett Date: Sun, 1 Feb 2015 07:43:02 -0700 Subject: [PATCH 01/16] Bug 1116855 - Tolerate any input register when storing bytes on x86, r=jandem. --- js/src/jit/shared/MacroAssembler-x86-shared.h | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/js/src/jit/shared/MacroAssembler-x86-shared.h b/js/src/jit/shared/MacroAssembler-x86-shared.h index b44629231537..a7f6adb14338 100644 --- a/js/src/jit/shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/shared/MacroAssembler-x86-shared.h @@ -650,6 +650,44 @@ class MacroAssemblerX86Shared : public Assembler Condition cond = testDoubleTruthy(truthy, reg); j(cond, label); } + + // Class which ensures that registers used in byte ops are compatible with + // such instructions, even if the original register passed in wasn't. This + // only applies to x86, as on x64 all registers are valid single byte regs. + // This doesn't lead to great code but helps to simplify code generation. + class AutoEnsureByteRegister { + MacroAssemblerX86Shared *masm; + Register reg_; + bool read_; + + public: + template + AutoEnsureByteRegister(MacroAssemblerX86Shared *masm, T address, Register reg, bool read) + : masm(masm), reg_(reg), read_(read) + { + if (!GeneralRegisterSet(Registers::SingleByteRegs).has(reg_)) { + MOZ_ASSERT(address.base != StackPointer); + masm->push(eax); + if (read) + masm->mov(reg_, eax); + } + } + + ~AutoEnsureByteRegister() { + if (!GeneralRegisterSet(Registers::SingleByteRegs).has(reg_)) { + if (!read_) + masm->mov(eax, reg_); + masm->pop(eax); + } + } + + Register reg() { + if (!GeneralRegisterSet(Registers::SingleByteRegs).has(reg_)) + return eax; + return reg_; + } + }; + void load8ZeroExtend(const Address &src, Register dest) { movzbl(Operand(src), dest); } @@ -662,11 +700,16 @@ class MacroAssemblerX86Shared : public Assembler void load8SignExtend(const BaseIndex &src, Register dest) { movsbl(Operand(src), dest); } - template - void store8(const S &src, const T &dest) { + template + void store8(Imm32 src, const T &dest) { movb(src, Operand(dest)); } template + void store8(Register src, const T &dest) { + AutoEnsureByteRegister ensure(this, dest, src, /* read = */ true); + movb(ensure.reg(), Operand(dest)); + } + template void compareExchange8ZeroExtend(const T &mem, Register oldval, Register newval, Register output) { MOZ_ASSERT(output == eax); MOZ_ASSERT(newval == ebx || newval == ecx || newval == edx); From e702b57de93c5f4ee006123268e37f7b459b2e3d Mon Sep 17 00:00:00 2001 From: Brian Hackett Date: Sun, 1 Feb 2015 09:50:04 -0700 Subject: [PATCH 02/16] Bug 1116855 - Add JIT optimizations for unboxed objects, r=jandem. --- js/src/jit/BaselineIC.cpp | 216 +++++++++++- js/src/jit/BaselineIC.h | 151 +++++++- js/src/jit/BaselineInspector.cpp | 78 +++-- js/src/jit/BaselineInspector.h | 5 +- js/src/jit/CodeGenerator.cpp | 155 ++++++--- js/src/jit/IonBuilder.cpp | 401 +++++++++++++++++++--- js/src/jit/IonBuilder.h | 15 +- js/src/jit/IonCaches.cpp | 212 ++++++++++-- js/src/jit/IonCaches.h | 9 + js/src/jit/Lowering.cpp | 6 +- js/src/jit/MIR.cpp | 15 +- js/src/jit/MIR.h | 151 +++++--- js/src/jit/MacroAssembler.cpp | 252 +++++++++++++- js/src/jit/MacroAssembler.h | 16 +- js/src/jit/OptimizationTracking.h | 12 + js/src/jit/ScalarReplacement.cpp | 4 + js/src/jit/arm/Lowering-arm.cpp | 2 +- js/src/jit/arm/MacroAssembler-arm.cpp | 14 + js/src/jit/arm/MacroAssembler-arm.h | 17 +- js/src/jit/mips/Lowering-mips.cpp | 2 +- js/src/jit/mips/MacroAssembler-mips.h | 13 + js/src/jit/none/MacroAssembler-none.h | 1 + js/src/jit/shared/Lowering-x86-shared.cpp | 2 +- js/src/jit/x64/MacroAssembler-x64.h | 17 + js/src/jit/x86/MacroAssembler-x86.h | 16 + 25 files changed, 1531 insertions(+), 251 deletions(-) diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index dd0a2b14fc50..c25c9fa46e31 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -363,6 +363,11 @@ ICStub::trace(JSTracer *trc) } break; } + case ICStub::GetProp_Unboxed: { + ICGetProp_Unboxed *propStub = toGetProp_Unboxed(); + MarkTypeObject(trc, &propStub->type(), "baseline-getprop-unboxed-stub-type"); + break; + } case ICStub::GetProp_TypedObject: { ICGetProp_TypedObject *propStub = toGetProp_TypedObject(); MarkShape(trc, &propStub->shape(), "baseline-getprop-typedobject-stub-shape"); @@ -437,6 +442,11 @@ ICStub::trace(JSTracer *trc) } break; } + case ICStub::SetProp_Unboxed: { + ICSetProp_Unboxed *propStub = toSetProp_Unboxed(); + MarkTypeObject(trc, &propStub->type(), "baseline-setprop-unboxed-stub-type"); + break; + } case ICStub::SetProp_TypedObject: { ICSetProp_TypedObject *propStub = toSetProp_TypedObject(); MarkShape(trc, &propStub->shape(), "baseline-setprop-typedobject-stub-shape"); @@ -1410,8 +1420,9 @@ DoTypeUpdateFallback(JSContext *cx, BaselineFrame *frame, ICUpdatedStub *stub, H break; } case ICStub::SetProp_Native: - case ICStub::SetProp_NativeAdd: { - MOZ_ASSERT(obj->isNative()); + case ICStub::SetProp_NativeAdd: + case ICStub::SetProp_Unboxed: { + MOZ_ASSERT(obj->isNative() || obj->is()); jsbytecode *pc = stub->getChainFallback()->icEntry()->pc(script); if (*pc == JSOP_SETALIASEDVAR || *pc == JSOP_INITALIASEDLEXICAL) id = NameToId(ScopeCoordinateName(cx->runtime()->scopeCoordinateNameCache, script, pc)); @@ -6598,6 +6609,40 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, return true; } +static bool +TryAttachUnboxedGetPropStub(JSContext *cx, HandleScript script, + ICGetProp_Fallback *stub, HandlePropertyName name, HandleValue val, + bool *attached) +{ + MOZ_ASSERT(!*attached); + + if (!cx->runtime()->jitSupportsFloatingPoint) + return true; + + if (!val.isObject() || !val.toObject().is()) + return true; + Rooted obj(cx, &val.toObject().as()); + + const UnboxedLayout::Property *property = obj->layout().lookup(name); + if (!property) + return true; + + ICStub *monitorStub = stub->fallbackMonitorStub()->firstMonitorStub(); + + ICGetProp_Unboxed::Compiler compiler(cx, monitorStub, obj->type(), + property->offset + UnboxedPlainObject::offsetOfData(), + property->type); + ICStub *newStub = compiler.getStub(compiler.getStubSpace(script)); + if (!newStub) + return false; + stub->addNewStub(newStub); + + StripPreliminaryObjectStubs(cx, stub); + + *attached = true; + return true; +} + static bool TryAttachTypedObjectGetPropStub(JSContext *cx, HandleScript script, ICGetProp_Fallback *stub, HandlePropertyName name, HandleValue val, @@ -6845,6 +6890,11 @@ DoGetPropFallback(JSContext *cx, BaselineFrame *frame, ICGetProp_Fallback *stub_ if (attached) return true; + if (!TryAttachUnboxedGetPropStub(cx, script, stub, name, val, &attached)) + return false; + if (attached) + return true; + if (!TryAttachTypedObjectGetPropStub(cx, script, stub, name, val, &attached)) return false; if (attached) @@ -7755,6 +7805,39 @@ ICGetProp_Generic::Compiler::generateStubCode(MacroAssembler &masm) return true; } +bool +ICGetProp_Unboxed::Compiler::generateStubCode(MacroAssembler &masm) +{ + Label failure; + + GeneralRegisterSet regs(availableGeneralRegs(1)); + + Register scratch = regs.takeAnyExcluding(BaselineTailCallReg); + + // Object and type guard. + masm.branchTestObject(Assembler::NotEqual, R0, &failure); + Register object = masm.extractObject(R0, ExtractTemp0); + masm.loadPtr(Address(BaselineStubReg, ICGetProp_Unboxed::offsetOfType()), scratch); + masm.branchPtr(Assembler::NotEqual, Address(object, JSObject::offsetOfType()), scratch, + &failure); + + // Get the address being read from. + masm.load32(Address(BaselineStubReg, ICGetProp_Unboxed::offsetOfFieldOffset()), scratch); + + masm.loadUnboxedProperty(BaseIndex(object, scratch, TimesOne), fieldType_, TypedOrValueRegister(R0)); + + // Only monitor the result if its type might change. + if (fieldType_ == JSVAL_TYPE_OBJECT) + EmitEnterTypeMonitorIC(masm); + else + EmitReturnFromIC(masm); + + masm.bind(&failure); + EmitStubGuardFailure(masm); + + return true; +} + bool ICGetProp_TypedObject::Compiler::generateStubCode(MacroAssembler &masm) { @@ -8009,6 +8092,40 @@ TryAttachSetAccessorPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, return true; } +static bool +TryAttachUnboxedSetPropStub(JSContext *cx, HandleScript script, + ICSetProp_Fallback *stub, HandleId id, + HandleObject obj, HandleValue rhs, bool *attached) +{ + MOZ_ASSERT(!*attached); + + if (!cx->runtime()->jitSupportsFloatingPoint) + return true; + + if (!obj->is()) + return true; + + const UnboxedLayout::Property *property = obj->as().layout().lookup(id); + if (!property) + return true; + + ICSetProp_Unboxed::Compiler compiler(cx, obj->type(), + property->offset + UnboxedPlainObject::offsetOfData(), + property->type); + ICUpdatedStub *newStub = compiler.getStub(compiler.getStubSpace(script)); + if (!newStub) + return false; + if (compiler.needsUpdateStubs() && !newStub->addUpdateStubForValue(cx, script, obj, id, rhs)) + return false; + + stub->addNewStub(newStub); + + StripPreliminaryObjectStubs(cx, stub); + + *attached = true; + return true; +} + static bool TryAttachTypedObjectSetPropStub(JSContext *cx, HandleScript script, ICSetProp_Fallback *stub, HandleId id, @@ -8152,6 +8269,15 @@ DoSetPropFallback(JSContext *cx, BaselineFrame *frame, ICSetProp_Fallback *stub_ if (attached) return true; + if (!attached && + lhs.isObject() && + !TryAttachUnboxedSetPropStub(cx, script, stub, id, obj, rhs, &attached)) + { + return false; + } + if (attached) + return true; + if (!attached && lhs.isObject() && !TryAttachTypedObjectSetPropStub(cx, script, stub, id, obj, rhs, &attached)) @@ -8436,6 +8562,75 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm) return true; } +bool +ICSetProp_Unboxed::Compiler::generateStubCode(MacroAssembler &masm) +{ + Label failure; + + // Guard input is an object. + masm.branchTestObject(Assembler::NotEqual, R0, &failure); + + GeneralRegisterSet regs(availableGeneralRegs(2)); + Register scratch = regs.takeAny(); + + // Unbox and type guard. + Register object = masm.extractObject(R0, ExtractTemp0); + masm.loadPtr(Address(BaselineStubReg, ICSetProp_Unboxed::offsetOfType()), scratch); + masm.branchPtr(Assembler::NotEqual, Address(object, JSObject::offsetOfType()), scratch, + &failure); + + if (needsUpdateStubs()) { + // Stow both R0 and R1 (object and value). + masm.push(object); + masm.push(BaselineStubReg); + EmitStowICValues(masm, 2); + + // Move RHS into R0 for TypeUpdate check. + masm.moveValue(R1, R0); + + // Call the type update stub. + if (!callTypeUpdateIC(masm, sizeof(Value))) + return false; + + // Unstow R0 and R1 (object and key) + EmitUnstowICValues(masm, 2); + masm.pop(BaselineStubReg); + masm.pop(object); + + // Trigger post barriers here on the values being written. Fields which + // objects can be written to also need update stubs. + GeneralRegisterSet saveRegs; + saveRegs.add(R0); + saveRegs.add(R1); + saveRegs.addUnchecked(object); + saveRegs.add(BaselineStubReg); + emitPostWriteBarrierSlot(masm, object, R1, scratch, saveRegs); + } + + // Compute the address being written to. + masm.load32(Address(BaselineStubReg, ICSetProp_Unboxed::offsetOfFieldOffset()), scratch); + BaseIndex address(object, scratch, TimesOne); + + if (fieldType_ == JSVAL_TYPE_OBJECT) + EmitPreBarrier(masm, address, MIRType_Object); + else if (fieldType_ == JSVAL_TYPE_STRING) + EmitPreBarrier(masm, address, MIRType_String); + else + MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(fieldType_)); + + masm.storeUnboxedProperty(address, fieldType_, + ConstantOrRegister(TypedOrValueRegister(R1)), &failure); + + // The RHS has to be in R0. + masm.moveValue(R1, R0); + + EmitReturnFromIC(masm); + + masm.bind(&failure); + EmitStubGuardFailure(masm); + return true; +} + bool ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler &masm) { @@ -9066,27 +9261,26 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb // Remember the template object associated with any script being called // as a constructor, for later use during Ion compilation. - RootedPlainObject templateObject(cx); + RootedObject templateObject(cx); if (constructing) { JSObject *thisObject = CreateThisForFunction(cx, fun, MaybeSingletonObject); if (!thisObject) return false; - if (thisObject->is()) { - templateObject = &thisObject->as(); + if (thisObject->is() || thisObject->is()) { + templateObject = thisObject; // If we are calling a constructor for which the new script // properties analysis has not been performed yet, don't attach a // stub. After the analysis is performed, CreateThisForFunction may // start returning objects with a different type, and the Ion // compiler might get confused. - if (templateObject->type()->newScript() && - !templateObject->type()->newScript()->analyzed()) - { + types::TypeNewScript *newScript = templateObject->type()->newScript(); + if (newScript && !newScript->analyzed()) { // Clear the object just created from the preliminary objects // on the TypeNewScript, as it will not be used or filled in by // running code. - templateObject->type()->newScript()->unregisterNewObject(templateObject); + newScript->unregisterNewObject(&templateObject->as()); return true; } } @@ -11713,7 +11907,7 @@ ICSetProp_CallNative::Clone(JSContext *cx, ICStubSpace *space, ICStub *, } ICCall_Scripted::ICCall_Scripted(JitCode *stubCode, ICStub *firstMonitorStub, - HandleScript calleeScript, HandleNativeObject templateObject, + HandleScript calleeScript, HandleObject templateObject, uint32_t pcOffset) : ICMonitoredStub(ICStub::Call_Scripted, stubCode, firstMonitorStub), calleeScript_(calleeScript), @@ -11726,7 +11920,7 @@ ICCall_Scripted::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorSt ICCall_Scripted &other) { RootedScript calleeScript(cx, other.calleeScript_); - RootedNativeObject templateObject(cx, other.templateObject_); + RootedObject templateObject(cx, other.templateObject_); return New(space, other.jitCode(), firstMonitorStub, calleeScript, templateObject, other.pcOffset_); } diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index e84ddd86550a..d5bd544f4a53 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -430,6 +430,7 @@ class ICEntry _(GetProp_Native) \ _(GetProp_NativeDoesNotExist) \ _(GetProp_NativePrototype) \ + _(GetProp_Unboxed) \ _(GetProp_TypedObject) \ _(GetProp_CallScripted) \ _(GetProp_CallNative) \ @@ -444,6 +445,7 @@ class ICEntry _(SetProp_Fallback) \ _(SetProp_Native) \ _(SetProp_NativeAdd) \ + _(SetProp_Unboxed) \ _(SetProp_TypedObject) \ _(SetProp_CallScripted) \ _(SetProp_CallNative) \ @@ -4523,6 +4525,72 @@ class ICGetPropNativeDoesNotExistCompiler : public ICStubCompiler ICStub *getStub(ICStubSpace *space); }; +class ICGetProp_Unboxed : public ICMonitoredStub +{ + friend class ICStubSpace; + + HeapPtrTypeObject type_; + uint32_t fieldOffset_; + + ICGetProp_Unboxed(JitCode *stubCode, ICStub *firstMonitorStub, HandleTypeObject type, + uint32_t fieldOffset) + : ICMonitoredStub(ICStub::GetProp_Unboxed, stubCode, firstMonitorStub), + type_(type), fieldOffset_(fieldOffset) + { + (void) fieldOffset_; // Silence clang warning + } + + public: + static inline ICGetProp_Unboxed *New(ICStubSpace *space, JitCode *code, + ICStub *firstMonitorStub, HandleTypeObject shape, + uint32_t fieldOffset) + { + if (!code) + return nullptr; + return space->allocate(code, firstMonitorStub, shape, fieldOffset); + } + + HeapPtrTypeObject &type() { + return type_; + } + + static size_t offsetOfType() { + return offsetof(ICGetProp_Unboxed, type_); + } + static size_t offsetOfFieldOffset() { + return offsetof(ICGetProp_Unboxed, fieldOffset_); + } + + class Compiler : public ICStubCompiler { + protected: + ICStub *firstMonitorStub_; + RootedTypeObject type_; + uint32_t fieldOffset_; + JSValueType fieldType_; + + bool generateStubCode(MacroAssembler &masm); + + virtual int32_t getKey() const { + return static_cast(kind) | (static_cast(fieldType_)) << 16; + } + + public: + Compiler(JSContext *cx, ICStub *firstMonitorStub, + types::TypeObject *type, uint32_t fieldOffset, JSValueType fieldType) + : ICStubCompiler(cx, ICStub::GetProp_Unboxed), + firstMonitorStub_(firstMonitorStub), + type_(cx, type), + fieldOffset_(fieldOffset), + fieldType_(fieldType) + {} + + ICStub *getStub(ICStubSpace *space) { + return ICGetProp_Unboxed::New(space, getStubCode(), firstMonitorStub_, + type_, fieldOffset_); + } + }; +}; + static uint32_t SimpleTypeDescrKey(SimpleTypeDescr *descr) { @@ -5419,6 +5487,77 @@ class ICSetPropNativeAddCompiler : public ICStubCompiler ICUpdatedStub *getStub(ICStubSpace *space); }; +class ICSetProp_Unboxed : public ICUpdatedStub +{ + friend class ICStubSpace; + + HeapPtrTypeObject type_; + uint32_t fieldOffset_; + + ICSetProp_Unboxed(JitCode *stubCode, HandleTypeObject type, uint32_t fieldOffset) + : ICUpdatedStub(ICStub::SetProp_Unboxed, stubCode), + type_(type), + fieldOffset_(fieldOffset) + { + (void) fieldOffset_; // Silence clang warning + } + + public: + static inline ICSetProp_Unboxed *New(ICStubSpace *space, JitCode *code, + HandleTypeObject type, uint32_t fieldOffset) + { + if (!code) + return nullptr; + return space->allocate(code, type, fieldOffset); + } + + HeapPtrTypeObject &type() { + return type_; + } + + static size_t offsetOfType() { + return offsetof(ICSetProp_Unboxed, type_); + } + static size_t offsetOfFieldOffset() { + return offsetof(ICSetProp_Unboxed, fieldOffset_); + } + + class Compiler : public ICStubCompiler { + protected: + RootedTypeObject type_; + uint32_t fieldOffset_; + JSValueType fieldType_; + + bool generateStubCode(MacroAssembler &masm); + + virtual int32_t getKey() const { + return static_cast(kind) | + (static_cast(fieldType_) << 16); + } + + public: + Compiler(JSContext *cx, types::TypeObject *type, uint32_t fieldOffset, + JSValueType fieldType) + : ICStubCompiler(cx, ICStub::SetProp_Unboxed), + type_(cx, type), + fieldOffset_(fieldOffset), + fieldType_(fieldType) + {} + + ICUpdatedStub *getStub(ICStubSpace *space) { + ICUpdatedStub *stub = ICSetProp_Unboxed::New(space, getStubCode(), + type_, fieldOffset_); + if (!stub || !stub->initUpdatingChain(cx, space)) + return nullptr; + return stub; + } + + bool needsUpdateStubs() { + return fieldType_ == JSVAL_TYPE_OBJECT; + } + }; +}; + class ICSetProp_TypedObject : public ICUpdatedStub { friend class ICStubSpace; @@ -5799,17 +5938,17 @@ class ICCall_Scripted : public ICMonitoredStub protected: HeapPtrScript calleeScript_; - HeapPtrNativeObject templateObject_; + HeapPtrObject templateObject_; uint32_t pcOffset_; ICCall_Scripted(JitCode *stubCode, ICStub *firstMonitorStub, - HandleScript calleeScript, HandleNativeObject templateObject, + HandleScript calleeScript, HandleObject templateObject, uint32_t pcOffset); public: static inline ICCall_Scripted *New( ICStubSpace *space, JitCode *code, ICStub *firstMonitorStub, - HandleScript calleeScript, HandleNativeObject templateObject, + HandleScript calleeScript, HandleObject templateObject, uint32_t pcOffset) { if (!code) @@ -5824,7 +5963,7 @@ class ICCall_Scripted : public ICMonitoredStub HeapPtrScript &calleeScript() { return calleeScript_; } - HeapPtrNativeObject &templateObject() { + HeapPtrObject &templateObject() { return templateObject_; } @@ -5872,7 +6011,7 @@ class ICCallScriptedCompiler : public ICCallStubCompiler { bool isConstructing_; bool isSpread_; RootedScript calleeScript_; - RootedNativeObject templateObject_; + RootedObject templateObject_; uint32_t pcOffset_; bool generateStubCode(MacroAssembler &masm); @@ -5883,7 +6022,7 @@ class ICCallScriptedCompiler : public ICCallStubCompiler { public: ICCallScriptedCompiler(JSContext *cx, ICStub *firstMonitorStub, - HandleScript calleeScript, HandleNativeObject templateObject, + HandleScript calleeScript, HandleObject templateObject, bool isConstructing, bool isSpread, uint32_t pcOffset) : ICCallStubCompiler(cx, ICStub::Call_Scripted), firstMonitorStub_(firstMonitorStub), diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp index c9c38a835ec7..ace050314b78 100644 --- a/js/src/jit/BaselineInspector.cpp +++ b/js/src/jit/BaselineInspector.cpp @@ -80,12 +80,15 @@ SetElemICInspector::sawTypedArrayWrite() const } bool -BaselineInspector::maybeShapesForPropertyOp(jsbytecode *pc, ShapeVector &shapes) +BaselineInspector::maybeInfoForPropertyOp(jsbytecode *pc, + ShapeVector &nativeShapes, + TypeObjectVector &unboxedTypes) { - // Return a list of shapes seen by the baseline IC for the current op. - // An empty list indicates no shapes are known, or there was an uncacheable - // access. - MOZ_ASSERT(shapes.empty()); + // Return lists of native shapes and unboxed objects seen by the baseline + // IC for the current op. Empty lists indicate no shapes/types are known, + // or there was an uncacheable access. + MOZ_ASSERT(nativeShapes.empty()); + MOZ_ASSERT(unboxedTypes.empty()); if (!hasBaselineScript()) return true; @@ -95,43 +98,66 @@ BaselineInspector::maybeShapesForPropertyOp(jsbytecode *pc, ShapeVector &shapes) ICStub *stub = entry.firstStub(); while (stub->next()) { - Shape *shape; + Shape *shape = nullptr; + types::TypeObject *type = nullptr; if (stub->isGetProp_Native()) { shape = stub->toGetProp_Native()->shape(); } else if (stub->isSetProp_Native()) { shape = stub->toSetProp_Native()->shape(); + } else if (stub->isGetProp_Unboxed()) { + type = stub->toGetProp_Unboxed()->type(); + } else if (stub->isSetProp_Unboxed()) { + type = stub->toSetProp_Unboxed()->type(); } else { - shapes.clear(); + nativeShapes.clear(); + unboxedTypes.clear(); return true; } - // Don't add the same shape twice (this can happen if there are multiple - // SetProp_Native stubs with different TypeObject's). - bool found = false; - for (size_t i = 0; i < shapes.length(); i++) { - if (shapes[i] == shape) { - found = true; - break; + // Don't add the same shape/type twice (this can happen if there are + // multiple SetProp_Native stubs with different TypeObject's). + if (shape) { + bool found = false; + for (size_t i = 0; i < nativeShapes.length(); i++) { + if (nativeShapes[i] == shape) { + found = true; + break; + } } + if (!found && !nativeShapes.append(shape)) + return false; + } else { + bool found = false; + for (size_t i = 0; i < unboxedTypes.length(); i++) { + if (unboxedTypes[i] == type) { + found = true; + break; + } + } + if (!found && !unboxedTypes.append(type)) + return false; } - if (!found && !shapes.append(shape)) - return false; - stub = stub->next(); } if (stub->isGetProp_Fallback()) { - if (stub->toGetProp_Fallback()->hadUnoptimizableAccess()) - shapes.clear(); + if (stub->toGetProp_Fallback()->hadUnoptimizableAccess()) { + nativeShapes.clear(); + unboxedTypes.clear(); + } } else { - if (stub->toSetProp_Fallback()->hadUnoptimizableAccess()) - shapes.clear(); + if (stub->toSetProp_Fallback()->hadUnoptimizableAccess()) { + nativeShapes.clear(); + unboxedTypes.clear(); + } } - // Don't inline if there are more than 5 shapes. - if (shapes.length() > 5) - shapes.clear(); + // Don't inline if there are more than 5 shapes/types. + if (nativeShapes.length() + unboxedTypes.length() > 5) { + nativeShapes.clear(); + unboxedTypes.clear(); + } return true; } @@ -413,7 +439,7 @@ BaselineInspector::hasSeenDoubleResult(jsbytecode *pc) return false; } -NativeObject * +JSObject * BaselineInspector::getTemplateObject(jsbytecode *pc) { if (!hasBaselineScript()) @@ -429,7 +455,7 @@ BaselineInspector::getTemplateObject(jsbytecode *pc) case ICStub::Rest_Fallback: return stub->toRest_Fallback()->templateObject(); case ICStub::Call_Scripted: - if (NativeObject *obj = stub->toCall_Scripted()->templateObject()) + if (JSObject *obj = stub->toCall_Scripted()->templateObject()) return obj; break; default: diff --git a/js/src/jit/BaselineInspector.h b/js/src/jit/BaselineInspector.h index 6c42989e5837..232ca9187cc1 100644 --- a/js/src/jit/BaselineInspector.h +++ b/js/src/jit/BaselineInspector.h @@ -93,7 +93,8 @@ class BaselineInspector public: typedef Vector ShapeVector; - bool maybeShapesForPropertyOp(jsbytecode *pc, ShapeVector &shapes); + typedef Vector TypeObjectVector; + bool maybeInfoForPropertyOp(jsbytecode *pc, ShapeVector &nativeShapes, TypeObjectVector &unboxedTypes); SetElemICInspector setElemICInspector(jsbytecode *pc) { return makeICInspector(pc, ICStub::SetElem_Fallback); @@ -109,7 +110,7 @@ class BaselineInspector bool hasSeenDoubleResult(jsbytecode *pc); bool hasSeenNonStringIterMore(jsbytecode *pc); - NativeObject *getTemplateObject(jsbytecode *pc); + JSObject *getTemplateObject(jsbytecode *pc); JSObject *getTemplateObjectForNative(jsbytecode *pc, Native native); JSObject *getTemplateObjectForClassHook(jsbytecode *pc, const Class *clasp); diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 1aa1e44e7651..c9c763d41c7c 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -2233,33 +2233,62 @@ CodeGenerator::emitGetPropertyPolymorphic(LInstruction *ins, Register obj, Regis const TypedOrValueRegister &output) { MGetPropertyPolymorphic *mir = ins->mirRaw()->toGetPropertyPolymorphic(); - MOZ_ASSERT(mir->numShapes() > 1); - masm.loadObjShape(obj, scratch); + size_t total = mir->numUnboxedTypes() + mir->numShapes(); + MOZ_ASSERT(total > 1); + + bool typeInScratch = mir->numUnboxedTypes() > 1; + bool shapeInScratch = mir->numShapes() > 1; Label done; - for (size_t i = 0; i < mir->numShapes(); i++) { + + for (size_t i = 0; i < total; i++) { + bool unboxedType = i < mir->numUnboxedTypes(); + + ImmGCPtr comparePtr = unboxedType + ? ImmGCPtr(mir->unboxedType(i)) + : ImmGCPtr(mir->objShape(i - mir->numUnboxedTypes())); + Address addr(obj, unboxedType ? JSObject::offsetOfType() : JSObject::offsetOfShape()); + + if ((i == 0 && typeInScratch) || (i == mir->numUnboxedTypes() && shapeInScratch)) + masm.loadPtr(addr, scratch); + + bool inScratch = unboxedType ? typeInScratch : shapeInScratch; + Label next; - if (i == mir->numShapes() - 1) { - bailoutCmpPtr(Assembler::NotEqual, scratch, ImmGCPtr(mir->objShape(i)), - ins->snapshot()); + if (i == total - 1) { + if (inScratch) + bailoutCmpPtr(Assembler::NotEqual, scratch, comparePtr, ins->snapshot()); + else + bailoutCmpPtr(Assembler::NotEqual, addr, comparePtr, ins->snapshot()); } else { - masm.branchPtr(Assembler::NotEqual, scratch, ImmGCPtr(mir->objShape(i)), &next); + if (inScratch) + masm.branchPtr(Assembler::NotEqual, scratch, comparePtr, &next); + else + masm.branchPtr(Assembler::NotEqual, addr, comparePtr, &next); } - Shape *shape = mir->shape(i); - if (shape->slot() < shape->numFixedSlots()) { - // Fixed slot. - masm.loadTypedOrValue(Address(obj, NativeObject::getFixedSlotOffset(shape->slot())), - output); + if (unboxedType) { + const UnboxedLayout::Property *property = + mir->unboxedType(i)->unboxedLayout().lookup(mir->name()); + Address propertyAddr(obj, UnboxedPlainObject::offsetOfData() + property->offset); + + masm.loadUnboxedProperty(propertyAddr, property->type, output); } else { - // Dynamic slot. - uint32_t offset = (shape->slot() - shape->numFixedSlots()) * sizeof(js::Value); - masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), scratch); - masm.loadTypedOrValue(Address(scratch, offset), output); + Shape *shape = mir->shape(i - mir->numUnboxedTypes()); + if (shape->slot() < shape->numFixedSlots()) { + // Fixed slot. + masm.loadTypedOrValue(Address(obj, NativeObject::getFixedSlotOffset(shape->slot())), + output); + } else { + // Dynamic slot. + uint32_t offset = (shape->slot() - shape->numFixedSlots()) * sizeof(js::Value); + masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), scratch); + masm.loadTypedOrValue(Address(scratch, offset), output); + } } - if (i != mir->numShapes() - 1) + if (i != total - 1) masm.jump(&done); masm.bind(&next); } @@ -2291,37 +2320,72 @@ CodeGenerator::emitSetPropertyPolymorphic(LInstruction *ins, Register obj, Regis const ConstantOrRegister &value) { MSetPropertyPolymorphic *mir = ins->mirRaw()->toSetPropertyPolymorphic(); - MOZ_ASSERT(mir->numShapes() > 1); - masm.loadObjShape(obj, scratch); + size_t total = mir->numUnboxedTypes() + mir->numShapes(); + MOZ_ASSERT(total > 1); + + bool typeInScratch = mir->numUnboxedTypes() > 1; + bool shapeInScratch = mir->numShapes() > 1; Label done; - for (size_t i = 0; i < mir->numShapes(); i++) { + for (size_t i = 0; i < total; i++) { + bool unboxedType = i < mir->numUnboxedTypes(); + + ImmGCPtr comparePtr = unboxedType + ? ImmGCPtr(mir->unboxedType(i)) + : ImmGCPtr(mir->objShape(i - mir->numUnboxedTypes())); + Address addr(obj, unboxedType ? JSObject::offsetOfType() : JSObject::offsetOfShape()); + + if ((i == 0 && typeInScratch) || (i == mir->numUnboxedTypes() && shapeInScratch)) + masm.loadPtr(addr, scratch); + + bool inScratch = unboxedType ? typeInScratch : shapeInScratch; + Label next; - if (i == mir->numShapes() - 1) { - bailoutCmpPtr(Assembler::NotEqual, scratch, ImmGCPtr(mir->objShape(i)), - ins->snapshot()); + if (i == total - 1) { + if (inScratch) + bailoutCmpPtr(Assembler::NotEqual, scratch, comparePtr, ins->snapshot()); + else + bailoutCmpPtr(Assembler::NotEqual, addr, comparePtr, ins->snapshot()); } else { - masm.branchPtr(Assembler::NotEqual, scratch, ImmGCPtr(mir->objShape(i)), &next); + if (inScratch) + masm.branchPtr(Assembler::NotEqual, scratch, comparePtr, &next); + else + masm.branchPtr(Assembler::NotEqual, addr, comparePtr, &next); } - Shape *shape = mir->shape(i); - if (shape->slot() < shape->numFixedSlots()) { - // Fixed slot. - Address addr(obj, NativeObject::getFixedSlotOffset(shape->slot())); - if (mir->needsBarrier()) - emitPreBarrier(addr); - masm.storeConstantOrRegister(value, addr); + if (unboxedType) { + const UnboxedLayout::Property *property = + mir->unboxedType(i)->unboxedLayout().lookup(mir->name()); + Address propertyAddr(obj, UnboxedPlainObject::offsetOfData() + property->offset); + + if (property->type == JSVAL_TYPE_OBJECT) + masm.patchableCallPreBarrier(propertyAddr, MIRType_Object); + else if (property->type == JSVAL_TYPE_STRING) + masm.patchableCallPreBarrier(propertyAddr, MIRType_String); + else + MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(property->type)); + + masm.storeUnboxedProperty(propertyAddr, property->type, value, nullptr); } else { - // Dynamic slot. - masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), scratch); - Address addr(scratch, (shape->slot() - shape->numFixedSlots()) * sizeof(js::Value)); - if (mir->needsBarrier()) - emitPreBarrier(addr); - masm.storeConstantOrRegister(value, addr); + Shape *shape = mir->shape(i - mir->numUnboxedTypes()); + if (shape->slot() < shape->numFixedSlots()) { + // Fixed slot. + Address addr(obj, NativeObject::getFixedSlotOffset(shape->slot())); + if (mir->needsBarrier()) + emitPreBarrier(addr); + masm.storeConstantOrRegister(value, addr); + } else { + // Dynamic slot. + masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), scratch); + Address addr(scratch, (shape->slot() - shape->numFixedSlots()) * sizeof(js::Value)); + if (mir->needsBarrier()) + emitPreBarrier(addr); + masm.storeConstantOrRegister(value, addr); + } } - if (i != mir->numShapes() - 1) + if (i != total - 1) masm.jump(&done); masm.bind(&next); } @@ -4573,7 +4637,7 @@ static const VMFunction NewGCObjectInfo = void CodeGenerator::visitCreateThisWithTemplate(LCreateThisWithTemplate *lir) { - PlainObject *templateObject = lir->mir()->templateObject(); + JSObject *templateObject = lir->mir()->templateObject(); gc::AllocKind allocKind = templateObject->asTenured().getAllocKind(); gc::InitialHeap initialHeap = lir->mir()->initialHeap(); const js::Class *clasp = templateObject->type()->clasp(); @@ -4591,7 +4655,8 @@ CodeGenerator::visitCreateThisWithTemplate(LCreateThisWithTemplate *lir) // Initialize based on the templateObject. masm.bind(ool->rejoin()); - bool initFixedSlots = ShouldInitFixedSlots(lir, templateObject); + bool initFixedSlots = !templateObject->is() || + ShouldInitFixedSlots(lir, &templateObject->as()); masm.initGCThing(objReg, tempReg, templateObject, initFixedSlots); } @@ -8373,8 +8438,8 @@ CodeGenerator::visitLoadUnboxedPointerT(LLoadUnboxedPointerT *lir) bool bailOnNull; int32_t offsetAdjustment; if (lir->mir()->isLoadUnboxedObjectOrNull()) { - MOZ_ASSERT(lir->mir()->toLoadUnboxedObjectOrNull()->bailOnNull()); - bailOnNull = true; + bailOnNull = lir->mir()->toLoadUnboxedObjectOrNull()->nullBehavior() != + MLoadUnboxedObjectOrNull::NullNotPossible; offsetAdjustment = lir->mir()->toLoadUnboxedObjectOrNull()->offsetAdjustment(); } else if (lir->mir()->isLoadUnboxedString()) { bailOnNull = false; @@ -8411,11 +8476,13 @@ CodeGenerator::visitLoadTypedArrayElement(LLoadTypedArrayElement *lir) Label fail; if (lir->index()->isConstant()) { Address source(elements, ToInt32(lir->index()) * width + lir->mir()->offsetAdjustment()); - masm.loadFromTypedArray(arrayType, source, out, temp, &fail); + masm.loadFromTypedArray(arrayType, source, out, temp, &fail, + lir->mir()->canonicalizeDoubles()); } else { BaseIndex source(elements, ToRegister(lir->index()), ScaleFromElemWidth(width), lir->mir()->offsetAdjustment()); - masm.loadFromTypedArray(arrayType, source, out, temp, &fail); + masm.loadFromTypedArray(arrayType, source, out, temp, &fail, + lir->mir()->canonicalizeDoubles()); } if (fail.used()) diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index c442831b8365..e60e0be0d217 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -5514,7 +5514,9 @@ IonBuilder::createThisScriptedSingleton(JSFunction *target, MDefinition *callee) return nullptr; JSObject *templateObject = inspector->getTemplateObject(pc); - if (!templateObject || !templateObject->is()) + if (!templateObject) + return nullptr; + if (!templateObject->is() && !templateObject->is()) return nullptr; if (!templateObject->hasTenuredProto() || templateObject->getProto() != proto) return nullptr; @@ -6181,7 +6183,7 @@ IonBuilder::jsop_compare(JSOp op) bool IonBuilder::jsop_newarray(uint32_t count) { - NativeObject *templateObject = inspector->getTemplateObject(pc); + JSObject *templateObject = inspector->getTemplateObject(pc); if (!templateObject) { if (info().analysisMode() == Analysis_ArgumentsUsage) { MUnknownValue *unknown = MUnknownValue::New(alloc()); @@ -6218,9 +6220,9 @@ IonBuilder::jsop_newarray(uint32_t count) ins->resultTypeSet()->convertDoubleElements(constraints()); if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles) - templateObject->setShouldConvertDoubleElements(); + templateObject->as().setShouldConvertDoubleElements(); else - templateObject->clearShouldConvertDoubleElements(); + templateObject->as().clearShouldConvertDoubleElements(); return true; } @@ -6811,7 +6813,8 @@ IonBuilder::maybeInsertResume() static bool ClassHasEffectlessLookup(const Class *clasp, PropertyName *name) { - return clasp->isNative() && !clasp->ops.lookupGeneric; + return (clasp == &UnboxedPlainObject::class_) || + (clasp->isNative() && !clasp->ops.lookupGeneric); } static bool @@ -7741,9 +7744,13 @@ IonBuilder::pushReferenceLoadFromTypedObject(MDefinition *typedObj, // there is no other barrier needed we include the null bailout with // MLoadUnboxedObjectOrNull, which avoids the need to box the result // for a type barrier instruction. - bool bailOnNull = barrier == BarrierKind::NoBarrier && - !observedTypes->hasType(types::Type::NullType()); - load = MLoadUnboxedObjectOrNull::New(alloc(), elements, scaledOffset, bailOnNull, adjustment); + MLoadUnboxedObjectOrNull::NullBehavior nullBehavior; + if (barrier == BarrierKind::NoBarrier && !observedTypes->hasType(types::Type::NullType())) + nullBehavior = MLoadUnboxedObjectOrNull::BailOnNull; + else + nullBehavior = MLoadUnboxedObjectOrNull::HandleNull; + load = MLoadUnboxedObjectOrNull::New(alloc(), elements, scaledOffset, nullBehavior, + adjustment); break; } case ReferenceTypeDescr::TYPE_STRING: { @@ -9244,7 +9251,7 @@ IonBuilder::getDefiniteSlot(types::TemporaryTypeSet *types, PropertyName *name) if (slot == UINT32_MAX) { slot = propertySlot; } else if (slot != propertySlot) { - trackOptimizationOutcome(TrackedOutcome::NotFixedSlot); + trackOptimizationOutcome(TrackedOutcome::InconsistentFixedSlot); return UINT32_MAX; } } @@ -9252,6 +9259,58 @@ IonBuilder::getDefiniteSlot(types::TemporaryTypeSet *types, PropertyName *name) return slot; } +uint32_t +IonBuilder::getUnboxedOffset(types::TemporaryTypeSet *types, PropertyName *name, JSValueType *punboxedType) +{ + if (!types || types->unknownObject()) { + trackOptimizationOutcome(TrackedOutcome::NoTypeInfo); + return UINT32_MAX; + } + + uint32_t offset = UINT32_MAX; + + for (size_t i = 0; i < types->getObjectCount(); i++) { + types::TypeObjectKey *type = types->getObject(i); + if (!type) + continue; + + if (type->unknownProperties()) { + trackOptimizationOutcome(TrackedOutcome::UnknownProperties); + return UINT32_MAX; + } + + if (type->singleton()) { + trackOptimizationOutcome(TrackedOutcome::Singleton); + return UINT32_MAX; + } + + UnboxedLayout *layout = type->asTypeObject()->maybeUnboxedLayout(); + if (!layout) { + trackOptimizationOutcome(TrackedOutcome::NotUnboxed); + return UINT32_MAX; + } + + const UnboxedLayout::Property *property = layout->lookup(name); + if (!property) { + trackOptimizationOutcome(TrackedOutcome::StructNoField); + return UINT32_MAX; + } + + if (offset == UINT32_MAX) { + offset = property->offset; + *punboxedType = property->type; + } else if (offset != property->offset) { + trackOptimizationOutcome(TrackedOutcome::InconsistentFieldOffset); + return UINT32_MAX; + } else if (*punboxedType != property->type) { + trackOptimizationOutcome(TrackedOutcome::InconsistentFieldType); + return UINT32_MAX; + } + } + + return offset; +} + bool IonBuilder::jsop_runonce() { @@ -9679,6 +9738,11 @@ IonBuilder::jsop_getprop(PropertyName *name) if (!getPropTryDefiniteSlot(&emitted, obj, name, barrier, types) || emitted) return emitted; + // Try to emit loads from unboxed objects. + trackOptimizationAttempt(TrackedStrategy::GetProp_Unboxed); + if (!getPropTryUnboxed(&emitted, obj, name, barrier, types) || emitted) + return emitted; + // Try to inline a common property getter, or make a call. trackOptimizationAttempt(TrackedStrategy::GetProp_CommonGetter); if (!getPropTryCommonGetter(&emitted, obj, name, types) || emitted) @@ -10007,6 +10071,92 @@ IonBuilder::getPropTryDefiniteSlot(bool *emitted, MDefinition *obj, PropertyName return true; } +MInstruction * +IonBuilder::loadUnboxedProperty(MDefinition *obj, size_t offset, JSValueType unboxedType, + BarrierKind barrier, types::TemporaryTypeSet *types) +{ + size_t scaledOffsetConstant = offset / UnboxedTypeSize(unboxedType); + MInstruction *scaledOffset = MConstant::New(alloc(), Int32Value(scaledOffsetConstant)); + current->add(scaledOffset); + + MInstruction *load; + switch (unboxedType) { + case JSVAL_TYPE_BOOLEAN: + load = MLoadTypedArrayElement::New(alloc(), obj, scaledOffset, Scalar::Uint8, + DoesNotRequireMemoryBarrier, + UnboxedPlainObject::offsetOfData()); + load->setResultType(MIRType_Boolean); + break; + + case JSVAL_TYPE_INT32: + load = MLoadTypedArrayElement::New(alloc(), obj, scaledOffset, Scalar::Int32, + DoesNotRequireMemoryBarrier, + UnboxedPlainObject::offsetOfData()); + load->setResultType(MIRType_Int32); + break; + + case JSVAL_TYPE_DOUBLE: + load = MLoadTypedArrayElement::New(alloc(), obj, scaledOffset, Scalar::Float64, + DoesNotRequireMemoryBarrier, + UnboxedPlainObject::offsetOfData(), + /* canonicalizeDoubles = */ false); + load->setResultType(MIRType_Double); + break; + + case JSVAL_TYPE_STRING: + load = MLoadUnboxedString::New(alloc(), obj, scaledOffset, + UnboxedPlainObject::offsetOfData()); + break; + + case JSVAL_TYPE_OBJECT: { + MLoadUnboxedObjectOrNull::NullBehavior nullBehavior; + if (types->hasType(types::Type::NullType()) || barrier != BarrierKind::NoBarrier) + nullBehavior = MLoadUnboxedObjectOrNull::HandleNull; + else + nullBehavior = MLoadUnboxedObjectOrNull::NullNotPossible; + load = MLoadUnboxedObjectOrNull::New(alloc(), obj, scaledOffset, nullBehavior, + UnboxedPlainObject::offsetOfData()); + break; + } + + default: + MOZ_CRASH(); + } + + current->add(load); + return load; +} + +bool +IonBuilder::getPropTryUnboxed(bool *emitted, MDefinition *obj, PropertyName *name, + BarrierKind barrier, types::TemporaryTypeSet *types) +{ + MOZ_ASSERT(*emitted == false); + + JSValueType unboxedType; + uint32_t offset = getUnboxedOffset(obj->resultTypeSet(), name, &unboxedType); + if (offset == UINT32_MAX) + return true; + + if (obj->type() != MIRType_Object) { + MGuardObject *guard = MGuardObject::New(alloc(), obj); + current->add(guard); + obj = guard; + } + + if (unboxedType != JSVAL_TYPE_OBJECT) + barrier = BarrierKind::NoBarrier; + + MInstruction *load = loadUnboxedProperty(obj, offset, unboxedType, barrier, types); + current->push(load); + + if (!pushTypeBarrier(load, types, barrier)) + return false; + + *emitted = true; + return true; +} + bool IonBuilder::getPropTryCommonGetter(bool *emitted, MDefinition *obj, PropertyName *name, types::TemporaryTypeSet *types) @@ -10135,16 +10285,24 @@ IonBuilder::getPropTryCommonGetter(bool *emitted, MDefinition *obj, PropertyName return true; } -static bool -CanInlinePropertyOpShapes(const BaselineInspector::ShapeVector &shapes) +bool +IonBuilder::canInlinePropertyOpShapes(const BaselineInspector::ShapeVector &nativeShapes, + const BaselineInspector::TypeObjectVector &unboxedTypes) { - for (size_t i = 0; i < shapes.length(); i++) { + if (nativeShapes.empty() && unboxedTypes.empty()) { + trackOptimizationOutcome(TrackedOutcome::NoShapeInfo); + return false; + } + + for (size_t i = 0; i < nativeShapes.length(); i++) { // We inline the property access as long as the shape is not in // dictionary mode. We cannot be sure that the shape is still a // lastProperty, and calling Shape::search() on dictionary mode // shapes that aren't lastProperty is invalid. - if (shapes[i]->inDictionary()) + if (nativeShapes[i]->inDictionary()) { + trackOptimizationOutcome(TrackedOutcome::InDictionaryMode); return false; + } } return true; @@ -10154,7 +10312,6 @@ static bool GetPropertyShapes(jsid id, const BaselineInspector::ShapeVector &shapes, BaselineInspector::ShapeVector &propShapes, bool *sameSlot) { - MOZ_ASSERT(shapes.length() > 1); MOZ_ASSERT(propShapes.empty()); if (!propShapes.reserve(shapes.length())) @@ -10190,30 +10347,24 @@ IonBuilder::getPropTryInlineAccess(bool *emitted, MDefinition *obj, PropertyName return true; } - BaselineInspector::ShapeVector shapes(alloc()); - if (!inspector->maybeShapesForPropertyOp(pc, shapes)) + BaselineInspector::ShapeVector nativeShapes(alloc()); + BaselineInspector::TypeObjectVector unboxedTypes(alloc()); + if (!inspector->maybeInfoForPropertyOp(pc, nativeShapes, unboxedTypes)) return false; - if (shapes.empty()) { - trackOptimizationOutcome(TrackedOutcome::NoShapeInfo); + if (!canInlinePropertyOpShapes(nativeShapes, unboxedTypes)) return true; - } - - if (!CanInlinePropertyOpShapes(shapes)) { - trackOptimizationOutcome(TrackedOutcome::InDictionaryMode); - return true; - } MIRType rvalType = types->getKnownMIRType(); if (barrier != BarrierKind::NoBarrier || IsNullOrUndefined(rvalType)) rvalType = MIRType_Value; - if (shapes.length() == 1) { + if (nativeShapes.length() == 1 && unboxedTypes.empty()) { // In the monomorphic case, use separate ShapeGuard and LoadSlot // instructions. spew("Inlining monomorphic GETPROP"); - Shape *objShape = shapes[0]; + Shape *objShape = nativeShapes[0]; obj = addShapeGuard(obj, objShape, Bailout_ShapeGuard); Shape *shape = objShape->searchLinear(NameToId(name)); @@ -10227,15 +10378,39 @@ IonBuilder::getPropTryInlineAccess(bool *emitted, MDefinition *obj, PropertyName return true; } - MOZ_ASSERT(shapes.length() > 1); + if (nativeShapes.empty() && unboxedTypes.length() == 1) { + spew("Inlining monomorphic unboxed GETPROP"); + + types::TypeObject *unboxedType = unboxedTypes[0]; + + // Failures in this type guard should be treated the same as a shape guard failure. + obj = MGuardObjectType::New(alloc(), obj, unboxedType, /* bailOnEquality = */ false, + Bailout_ShapeGuard); + current->add(obj->toInstruction()); + + if (failedShapeGuard_) + obj->toGuardObjectType()->setNotMovable(); + + const UnboxedLayout::Property *property = unboxedType->unboxedLayout().lookup(name); + MInstruction *load = loadUnboxedProperty(obj, property->offset, property->type, barrier, types); + current->push(load); + + if (!pushTypeBarrier(load, types, barrier)) + return false; + + *emitted = true; + return true; + } + + MOZ_ASSERT(nativeShapes.length() + unboxedTypes.length() > 1); spew("Inlining polymorphic GETPROP"); BaselineInspector::ShapeVector propShapes(alloc()); bool sameSlot; - if (!GetPropertyShapes(NameToId(name), shapes, propShapes, &sameSlot)) + if (!GetPropertyShapes(NameToId(name), nativeShapes, propShapes, &sameSlot)) return false; - if (sameSlot) { + if (sameSlot && unboxedTypes.empty()) { MGuardShapePolymorphic *guard = MGuardShapePolymorphic::New(alloc(), obj); current->add(guard); obj = guard; @@ -10243,8 +10418,8 @@ IonBuilder::getPropTryInlineAccess(bool *emitted, MDefinition *obj, PropertyName if (failedShapeGuard_) guard->setNotMovable(); - for (size_t i = 0; i < shapes.length(); i++) { - if (!guard->addShape(shapes[i])) + for (size_t i = 0; i < nativeShapes.length(); i++) { + if (!guard->addShape(nativeShapes[i])) return false; } @@ -10260,8 +10435,13 @@ IonBuilder::getPropTryInlineAccess(bool *emitted, MDefinition *obj, PropertyName current->add(load); current->push(load); - for (size_t i = 0; i < shapes.length(); i++) { - if (!load->addShape(shapes[i], propShapes[i])) + for (size_t i = 0; i < nativeShapes.length(); i++) { + if (!load->addShape(nativeShapes[i], propShapes[i])) + return false; + } + + for (size_t i = 0; i < unboxedTypes.length(); i++) { + if (!load->addUnboxedType(unboxedTypes[i])) return false; } @@ -10447,10 +10627,6 @@ IonBuilder::jsop_setprop(PropertyName *name) return resumeAfter(ins); } - // Add post barrier if needed. - if (NeedsPostBarrier(info(), value)) - current->add(MPostWriteBarrier::New(alloc(), obj, value)); - // Try to inline a common property setter, or make a call. trackOptimizationAttempt(TrackedStrategy::SetProp_CommonSetter); if (!setPropTryCommonSetter(&emitted, obj, name, value) || emitted) @@ -10465,6 +10641,16 @@ IonBuilder::jsop_setprop(PropertyName *name) bool barrier = PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &obj, name, &value, /* canModify = */ true); + // Try to emit stores to unboxed objects. + trackOptimizationAttempt(TrackedStrategy::SetProp_Unboxed); + if (!setPropTryUnboxed(&emitted, obj, name, value, barrier, objTypes) || emitted) + return emitted; + + // Add post barrier if needed. The instructions above manage any post + // barriers they need directly. + if (NeedsPostBarrier(info(), value)) + current->add(MPostWriteBarrier::New(alloc(), obj, value)); + // Try to emit store from definite slots. trackOptimizationAttempt(TrackedStrategy::SetProp_DefiniteSlot); if (!setPropTryDefiniteSlot(&emitted, obj, name, value, barrier, objTypes) || emitted) @@ -10750,6 +10936,86 @@ IonBuilder::setPropTryDefiniteSlot(bool *emitted, MDefinition *obj, return true; } +MInstruction * +IonBuilder::storeUnboxedProperty(MDefinition *obj, size_t offset, JSValueType unboxedType, + MDefinition *value) +{ + size_t scaledOffsetConstant = offset / UnboxedTypeSize(unboxedType); + MInstruction *scaledOffset = MConstant::New(alloc(), Int32Value(scaledOffsetConstant)); + current->add(scaledOffset); + + MInstruction *store; + switch (unboxedType) { + case JSVAL_TYPE_BOOLEAN: + store = MStoreTypedArrayElement::New(alloc(), obj, scaledOffset, value, Scalar::Uint8, + DoesNotRequireMemoryBarrier, + UnboxedPlainObject::offsetOfData()); + break; + + case JSVAL_TYPE_INT32: + store = MStoreTypedArrayElement::New(alloc(), obj, scaledOffset, value, Scalar::Int32, + DoesNotRequireMemoryBarrier, + UnboxedPlainObject::offsetOfData()); + break; + + case JSVAL_TYPE_DOUBLE: + store = MStoreTypedArrayElement::New(alloc(), obj, scaledOffset, value, Scalar::Float64, + DoesNotRequireMemoryBarrier, + UnboxedPlainObject::offsetOfData()); + break; + + case JSVAL_TYPE_STRING: + store = MStoreUnboxedString::New(alloc(), obj, scaledOffset, value, + UnboxedPlainObject::offsetOfData()); + break; + + case JSVAL_TYPE_OBJECT: + store = MStoreUnboxedObjectOrNull::New(alloc(), obj, scaledOffset, value, obj, + UnboxedPlainObject::offsetOfData()); + break; + + default: + MOZ_CRASH(); + } + + current->add(store); + return store; +} + +bool +IonBuilder::setPropTryUnboxed(bool *emitted, MDefinition *obj, + PropertyName *name, MDefinition *value, + bool barrier, types::TemporaryTypeSet *objTypes) +{ + MOZ_ASSERT(*emitted == false); + + if (barrier) { + trackOptimizationOutcome(TrackedOutcome::NeedsTypeBarrier); + return true; + } + + JSValueType unboxedType; + uint32_t offset = getUnboxedOffset(obj->resultTypeSet(), name, &unboxedType); + if (offset == UINT32_MAX) + return true; + + if (obj->type() != MIRType_Object) { + MGuardObject *guard = MGuardObject::New(alloc(), obj); + current->add(guard); + obj = guard; + } + + MInstruction *store = storeUnboxedProperty(obj, offset, unboxedType, value); + + current->push(value); + + if (!resumeAfter(store)) + return false; + + *emitted = true; + return true; +} + bool IonBuilder::setPropTryInlineAccess(bool *emitted, MDefinition *obj, PropertyName *name, MDefinition *value, @@ -10762,28 +11028,22 @@ IonBuilder::setPropTryInlineAccess(bool *emitted, MDefinition *obj, return true; } - BaselineInspector::ShapeVector shapes(alloc()); - if (!inspector->maybeShapesForPropertyOp(pc, shapes)) + BaselineInspector::ShapeVector nativeShapes(alloc()); + BaselineInspector::TypeObjectVector unboxedTypes(alloc()); + if (!inspector->maybeInfoForPropertyOp(pc, nativeShapes, unboxedTypes)) return false; - if (shapes.empty()) { - trackOptimizationOutcome(TrackedOutcome::NoShapeInfo); + if (!canInlinePropertyOpShapes(nativeShapes, unboxedTypes)) return true; - } - if (!CanInlinePropertyOpShapes(shapes)) { - trackOptimizationOutcome(TrackedOutcome::InDictionaryMode); - return true; - } - - if (shapes.length() == 1) { + if (nativeShapes.length() == 1 && unboxedTypes.empty()) { spew("Inlining monomorphic SETPROP"); // The Baseline IC was monomorphic, so we inline the property access as // long as the shape is not in dictionary mode. We cannot be sure // that the shape is still a lastProperty, and calling Shape::search // on dictionary mode shapes that aren't lastProperty is invalid. - Shape *objShape = shapes[0]; + Shape *objShape = nativeShapes[0]; obj = addShapeGuard(obj, objShape, Bailout_ShapeGuard); Shape *shape = objShape->searchLinear(NameToId(name)); @@ -10798,15 +11058,37 @@ IonBuilder::setPropTryInlineAccess(bool *emitted, MDefinition *obj, return true; } - MOZ_ASSERT(shapes.length() > 1); + if (nativeShapes.empty() && unboxedTypes.length() == 1) { + spew("Inlining monomorphic unboxed SETPROP"); + + types::TypeObject *unboxedType = unboxedTypes[0]; + + // Failures in this type guard should be treated the same as a shape guard failure. + obj = MGuardObjectType::New(alloc(), obj, unboxedType, /* bailOnEquality = */ false, + Bailout_ShapeGuard); + current->add(obj->toInstruction()); + + if (failedShapeGuard_) + obj->toGuardObjectType()->setNotMovable(); + + const UnboxedLayout::Property *property = unboxedType->unboxedLayout().lookup(name); + storeUnboxedProperty(obj, property->offset, property->type, value); + + current->push(value); + + *emitted = true; + return true; + } + + MOZ_ASSERT(nativeShapes.length() + unboxedTypes.length() > 1); spew("Inlining polymorphic SETPROP"); BaselineInspector::ShapeVector propShapes(alloc()); bool sameSlot; - if (!GetPropertyShapes(NameToId(name), shapes, propShapes, &sameSlot)) + if (!GetPropertyShapes(NameToId(name), nativeShapes, propShapes, &sameSlot)) return false; - if (sameSlot) { + if (sameSlot && unboxedTypes.empty()) { MGuardShapePolymorphic *guard = MGuardShapePolymorphic::New(alloc(), obj); current->add(guard); obj = guard; @@ -10814,8 +11096,8 @@ IonBuilder::setPropTryInlineAccess(bool *emitted, MDefinition *obj, if (failedShapeGuard_) guard->setNotMovable(); - for (size_t i = 0; i < shapes.length(); i++) { - if (!guard->addShape(shapes[i])) + for (size_t i = 0; i < nativeShapes.length(); i++) { + if (!guard->addShape(nativeShapes[i])) return false; } @@ -10828,18 +11110,23 @@ IonBuilder::setPropTryInlineAccess(bool *emitted, MDefinition *obj, return true; } - MSetPropertyPolymorphic *ins = MSetPropertyPolymorphic::New(alloc(), obj, value); + MSetPropertyPolymorphic *ins = MSetPropertyPolymorphic::New(alloc(), obj, value, name); current->add(ins); current->push(value); - for (size_t i = 0; i < shapes.length(); i++) { - Shape *objShape = shapes[i]; + for (size_t i = 0; i < nativeShapes.length(); i++) { + Shape *objShape = nativeShapes[i]; Shape *shape = objShape->searchLinear(NameToId(name)); MOZ_ASSERT(shape); if (!ins->addShape(objShape, shape)) return false; } + for (size_t i = 0; i < unboxedTypes.length(); i++) { + if (!ins->addUnboxedType(unboxedTypes[i])) + return false; + } + if (objTypes->propertyNeedsBarrier(constraints(), NameToId(name))) ins->setNeedsBarrier(); diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 4f450ec032fb..28639a00db0a 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -12,6 +12,7 @@ #include "mozilla/LinkedList.h" +#include "jit/BaselineInspector.h" #include "jit/BytecodeAnalysis.h" #include "jit/IonAnalysis.h" #include "jit/IonOptimizationLevels.h" @@ -25,7 +26,6 @@ namespace jit { class CodeGenerator; class CallInfo; -class BaselineInspector; class BaselineFrameInspector; // Records information about a baseline frame for compilation that is stable @@ -423,6 +423,8 @@ class IonBuilder types::TemporaryTypeSet *types); bool getPropTryDefiniteSlot(bool *emitted, MDefinition *obj, PropertyName *name, BarrierKind barrier, types::TemporaryTypeSet *types); + bool getPropTryUnboxed(bool *emitted, MDefinition *obj, PropertyName *name, + BarrierKind barrier, types::TemporaryTypeSet *types); bool getPropTryCommonGetter(bool *emitted, MDefinition *obj, PropertyName *name, types::TemporaryTypeSet *types); bool getPropTryInlineAccess(bool *emitted, MDefinition *obj, PropertyName *name, @@ -453,6 +455,9 @@ class IonBuilder bool setPropTryDefiniteSlot(bool *emitted, MDefinition *obj, PropertyName *name, MDefinition *value, bool barrier, types::TemporaryTypeSet *objTypes); + bool setPropTryUnboxed(bool *emitted, MDefinition *obj, + PropertyName *name, MDefinition *value, + bool barrier, types::TemporaryTypeSet *objTypes); bool setPropTryInlineAccess(bool *emitted, MDefinition *obj, PropertyName *name, MDefinition *value, bool barrier, types::TemporaryTypeSet *objTypes); @@ -878,8 +883,16 @@ class IonBuilder bool testSingletonPropertyTypes(MDefinition *obj, JSObject *singleton, PropertyName *name, bool *testObject, bool *testString); uint32_t getDefiniteSlot(types::TemporaryTypeSet *types, PropertyName *name); + uint32_t getUnboxedOffset(types::TemporaryTypeSet *types, PropertyName *name, + JSValueType *punboxedType); + MInstruction *loadUnboxedProperty(MDefinition *obj, size_t offset, JSValueType unboxedType, + BarrierKind barrier, types::TemporaryTypeSet *types); + MInstruction *storeUnboxedProperty(MDefinition *obj, size_t offset, JSValueType unboxedType, + MDefinition *value); bool freezePropTypeSets(types::TemporaryTypeSet *types, JSObject *foundProto, PropertyName *name); + bool canInlinePropertyOpShapes(const BaselineInspector::ShapeVector &nativeShapes, + const BaselineInspector::TypeObjectVector &unboxedTypes); types::TemporaryTypeSet *bytecodeTypes(jsbytecode *pc); diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 98cfde4bc9d4..2b038b3d0cd0 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -769,7 +769,6 @@ GenerateReadSlot(JSContext *cx, IonScript *ion, MacroAssembler &masm, Shape *shape, Register object, TypedOrValueRegister output, Label *failures = nullptr) { - MOZ_ASSERT(obj->isNative()); // If there's a single jump to |failures|, we can patch the shape guard // jump directly. Otherwise, jump to the end of the stub, so there's a // common point to patch. @@ -781,11 +780,18 @@ GenerateReadSlot(JSContext *cx, IonScript *ion, MacroAssembler &masm, if (multipleFailureJumps && !failures) failures = &failures_; - // Guard on the shape of the object. - attacher.branchNextStubOrLabel(masm, Assembler::NotEqual, - Address(object, JSObject::offsetOfShape()), - ImmGCPtr(obj->lastProperty()), - failures); + // Guard on the shape or type of the object, depending on whether it is native. + if (obj->isNative()) { + attacher.branchNextStubOrLabel(masm, Assembler::NotEqual, + Address(object, JSObject::offsetOfShape()), + ImmGCPtr(obj->lastProperty()), + failures); + } else { + attacher.branchNextStubOrLabel(masm, Assembler::NotEqual, + Address(object, JSObject::offsetOfType()), + ImmGCPtr(obj->type()), + failures); + } // If we need a scratch register, use either an output register or the // object register. After this point, we cannot jump directly to @@ -876,6 +882,24 @@ GenerateReadSlot(JSContext *cx, IonScript *ion, MacroAssembler &masm, } +static void +GenerateReadUnboxed(JSContext *cx, IonScript *ion, MacroAssembler &masm, + IonCache::StubAttacher &attacher, JSObject *obj, + const UnboxedLayout::Property *property, + Register object, TypedOrValueRegister output) +{ + // Guard on the type of the object. + attacher.branchNextStub(masm, Assembler::NotEqual, + Address(object, JSObject::offsetOfType()), + ImmGCPtr(obj->type())); + + Address address(object, UnboxedPlainObject::offsetOfData() + property->offset); + + masm.loadUnboxedProperty(address, property->type, output); + + attacher.jumpRejoin(masm); +} + static bool EmitGetterCall(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher, JSObject *obj, @@ -1170,7 +1194,7 @@ CanAttachNativeGetProp(typename GetPropCache::Context cx, const GetPropCache &ca MutableHandleNativeObject holder, MutableHandleShape shape, bool skipArrayLen = false) { - if (!obj || !obj->isNative()) + if (!obj) return GetPropertyIC::CanAttachNone; // The lookup needs to be universally pure, otherwise we risk calling hooks out @@ -1305,6 +1329,30 @@ GetPropertyIC::tryAttachNative(JSContext *cx, HandleScript outerScript, IonScrip return linkAndAttachStub(cx, masm, attacher, ion, attachKind); } +bool +GetPropertyIC::tryAttachUnboxed(JSContext *cx, HandleScript outerScript, IonScript *ion, + HandleObject obj, HandlePropertyName name, + void *returnAddr, bool *emitted) +{ + MOZ_ASSERT(canAttachStub()); + MOZ_ASSERT(!*emitted); + MOZ_ASSERT(outerScript->ionScript() == ion); + + if (!obj->is()) + return true; + const UnboxedLayout::Property *property = obj->as().layout().lookup(name); + if (!property) + return true; + + *emitted = true; + + MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_); + + RepatchStubAppender attacher(*this); + GenerateReadUnboxed(cx, ion, masm, attacher, obj, property, object(), output()); + return linkAndAttachStub(cx, masm, attacher, ion, "read unboxed"); +} + bool GetPropertyIC::tryAttachTypedArrayLength(JSContext *cx, HandleScript outerScript, IonScript *ion, HandleObject obj, HandlePropertyName name, bool *emitted) @@ -1729,9 +1777,15 @@ GetPropertyIC::tryAttachStub(JSContext *cx, HandleScript outerScript, IonScript if (!*emitted && !tryAttachNative(cx, outerScript, ion, obj, name, returnAddr, emitted)) return false; + if (!*emitted && !tryAttachUnboxed(cx, outerScript, ion, obj, name, returnAddr, emitted)) + return false; + if (!*emitted && !tryAttachTypedArrayLength(cx, outerScript, ion, obj, name, emitted)) return false; + if (!*emitted) + JitSpew(JitSpew_IonIC, "Failed to attach GETPROP cache"); + return true; } @@ -1836,6 +1890,26 @@ IonCache::destroy() { } +// Jump to failure if a value being written is not a property for obj/id. +// This might clobber |object|. +static void +CheckTypeSetForWrite(MacroAssembler &masm, JSObject *obj, jsid id, + Register object, ConstantOrRegister value, Label *failure) +{ + TypedOrValueRegister valReg = value.reg(); + types::TypeObject *type = obj->type(); + if (type->unknownProperties()) + return; + types::HeapTypeSet *propTypes = type->maybeGetProperty(id); + MOZ_ASSERT(propTypes); + + // guardTypeSet can read from type sets without triggering read barriers. + types::TypeSet::readBarrier(propTypes); + + Register scratch = object; + masm.guardTypeSet(valReg, propTypes, BarrierKind::TypeSet, scratch, failure); +} + static void GenerateSetSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher, NativeObject *obj, Shape *shape, Register object, ConstantOrRegister value, @@ -1861,18 +1935,8 @@ GenerateSetSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &att ImmGCPtr(type), &failures); if (checkTypeset) { - TypedOrValueRegister valReg = value.reg(); - types::HeapTypeSet *propTypes = type->maybeGetProperty(shape->propid()); - MOZ_ASSERT(propTypes); - MOZ_ASSERT(!propTypes->unknown()); - - // guardTypeSet can read from type sets without triggering read barriers. - types::TypeSet::readBarrier(propTypes); - - Register scratchReg = object; - masm.push(scratchReg); - - masm.guardTypeSet(valReg, propTypes, BarrierKind::TypeSet, scratchReg, &barrierFailure); + masm.push(object); + CheckTypeSetForWrite(masm, obj, shape->propid(), object, value, &barrierFailure); masm.pop(object); } } @@ -2420,17 +2484,7 @@ GenerateAddSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &att // Guard that the incoming value is in the type set for the property // if a type barrier is required. if (checkTypeset) { - TypedOrValueRegister valReg = value.reg(); - types::TypeObject *type = obj->type(); - types::HeapTypeSet *propTypes = type->maybeGetProperty(obj->lastProperty()->propid()); - MOZ_ASSERT(propTypes); - MOZ_ASSERT(!propTypes->unknown()); - - // guardTypeSet can read from type sets without triggering read barriers. - types::TypeSet::readBarrier(propTypes); - - Register scratchReg = object; - masm.guardTypeSet(valReg, propTypes, BarrierKind::TypeSet, scratchReg, &failuresPopObject); + CheckTypeSetForWrite(masm, obj, obj->lastProperty()->propid(), object, value, &failuresPopObject); masm.loadPtr(Address(StackPointer, 0), object); } @@ -2684,6 +2738,85 @@ CanAttachNativeSetProp(JSContext *cx, HandleObject obj, HandleId id, ConstantOrR return SetPropertyIC::CanAttachNone; } +static void +GenerateSetUnboxed(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher, + JSObject *obj, jsid id, uint32_t unboxedOffset, JSValueType unboxedType, + Register object, ConstantOrRegister value, bool checkTypeset) +{ + Label failure, failurePopObject; + + // Guard on the type of the object. + masm.branchPtr(Assembler::NotEqual, + Address(object, JSObject::offsetOfType()), + ImmGCPtr(obj->type()), &failure); + + if (checkTypeset) { + masm.push(object); + CheckTypeSetForWrite(masm, obj, id, object, value, &failurePopObject); + masm.pop(object); + } + + Address address(object, UnboxedPlainObject::offsetOfData() + unboxedOffset); + + if (cx->zone()->needsIncrementalBarrier()) { + if (unboxedType == JSVAL_TYPE_OBJECT) + masm.callPreBarrier(address, MIRType_Object); + else if (unboxedType == JSVAL_TYPE_STRING) + masm.callPreBarrier(address, MIRType_String); + else + MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(unboxedType)); + } + + // If the unboxed object's type has known properties, then instances have + // never been converted to native objects and the type set check performed + // above ensures the value being written can be stored in the unboxed + // object. + Label *storeFailure = obj->type()->unknownProperties() ? &failure : nullptr; + + masm.storeUnboxedProperty(address, unboxedType, value, storeFailure); + + attacher.jumpRejoin(masm); + + masm.bind(&failurePopObject); + masm.pop(object); + masm.bind(&failure); + + attacher.jumpNextStub(masm); +} + +bool +SetPropertyIC::attachSetUnboxed(JSContext *cx, HandleScript outerScript, IonScript *ion, + HandleObject obj, HandleId id, + uint32_t unboxedOffset, JSValueType unboxedType, + bool checkTypeset) +{ + MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_); + RepatchStubAppender attacher(*this); + GenerateSetUnboxed(cx, masm, attacher, obj, id, unboxedOffset, unboxedType, + object(), value(), needsTypeBarrier()); + return linkAndAttachStub(cx, masm, attacher, ion, "set_unboxed"); +} + +static bool +CanAttachSetUnboxed(JSContext *cx, HandleObject obj, HandleId id, ConstantOrRegister val, + bool needsTypeBarrier, bool *checkTypeset, + uint32_t *unboxedOffset, JSValueType *unboxedType) +{ + if (!obj->is()) + return false; + + const UnboxedLayout::Property *property = obj->as().layout().lookup(id); + if (property) { + if (needsTypeBarrier && !CanInlineSetPropTypeCheck(obj, id, val, checkTypeset)) + return false; + *unboxedOffset = property->offset; + *unboxedType = property->type; + return true; + } + + return false; +} + bool SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj, HandleValue value) @@ -2748,6 +2881,21 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj, return false; addedSetterStub = true; } + + checkTypeset = false; + uint32_t unboxedOffset; + JSValueType unboxedType; + if (!addedSetterStub && CanAttachSetUnboxed(cx, obj, id, cache.value(), + cache.needsTypeBarrier(), + &checkTypeset, &unboxedOffset, &unboxedType)) + { + if (!cache.attachSetUnboxed(cx, script, ion, obj, id, unboxedOffset, unboxedType, + checkTypeset)) + { + return false; + } + addedSetterStub = true; + } } uint32_t oldSlots = obj->is() ? obj->as().numDynamicSlots() : 0; @@ -2767,8 +2915,12 @@ SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj, RootedNativeObject nobj(cx, &obj->as()); if (!cache.attachAddSlot(cx, script, ion, nobj, oldShape, oldType, checkTypeset)) return false; + addedSetterStub = true; } + if (!addedSetterStub) + JitSpew(JitSpew_IonIC, "Failed to attach SETPROP cache"); + return true; } diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h index 85496f349a24..04c85d303604 100644 --- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -669,6 +669,10 @@ class GetPropertyIC : public RepatchIonCache HandleObject obj, HandlePropertyName name, void *returnAddr, bool *emitted); + bool tryAttachUnboxed(JSContext *cx, HandleScript outerScript, IonScript *ion, + HandleObject obj, HandlePropertyName name, + void *returnAddr, bool *emitted); + bool tryAttachTypedArrayLength(JSContext *cx, HandleScript outerScript, IonScript *ion, HandleObject obj, HandlePropertyName name, bool *emitted); @@ -747,6 +751,11 @@ class SetPropertyIC : public RepatchIonCache HandleNativeObject obj, HandleShape oldShape, HandleTypeObject oldType, bool checkTypeset); + bool attachSetUnboxed(JSContext *cx, HandleScript outerScript, IonScript *ion, + HandleObject obj, HandleId id, + uint32_t unboxedOffset, JSValueType unboxedType, + bool checkTypeset); + bool attachGenericProxy(JSContext *cx, HandleScript outerScript, IonScript *ion, void *returnAddr); diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 2732f364bd43..80d757061814 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2619,12 +2619,12 @@ LIRGenerator::visitLoadUnboxedObjectOrNull(MLoadUnboxedObjectOrNull *ins) if (ins->type() == MIRType_Object) { LLoadUnboxedPointerT *lir = new(alloc()) LLoadUnboxedPointerT(useRegister(ins->elements()), useRegisterOrConstant(ins->index())); - if (ins->bailOnNull()) + if (ins->nullBehavior() == MLoadUnboxedObjectOrNull::BailOnNull) assignSnapshot(lir, Bailout_TypeBarrierO); define(lir, ins); } else { MOZ_ASSERT(ins->type() == MIRType_Value); - MOZ_ASSERT(!ins->bailOnNull()); + MOZ_ASSERT(ins->nullBehavior() != MLoadUnboxedObjectOrNull::BailOnNull); LLoadUnboxedPointerV *lir = new(alloc()) LLoadUnboxedPointerV(useRegister(ins->elements()), useRegisterOrConstant(ins->index())); @@ -2848,7 +2848,7 @@ LIRGenerator::visitLoadTypedArrayElement(MLoadTypedArrayElement *ins) const LUse elements = useRegister(ins->elements()); const LAllocation index = useRegisterOrConstant(ins->index()); - MOZ_ASSERT(IsNumberType(ins->type())); + MOZ_ASSERT(IsNumberType(ins->type()) || ins->type() == MIRType_Boolean); // We need a temp register for Uint32Array with known double result. LDefinition tempDef = LDefinition::BogusTemp(); diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index fb9405f0a99f..e53244d979d6 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -3647,8 +3647,9 @@ MNewObject::shouldUseVM() const bool MCreateThisWithTemplate::canRecoverOnBailout() const { - MOZ_ASSERT(!templateObject()->denseElementsAreCopyOnWrite()); - MOZ_ASSERT(!templateObject()->is()); + MOZ_ASSERT(templateObject()->is() || templateObject()->is()); + MOZ_ASSERT_IF(templateObject()->is(), + !templateObject()->as().denseElementsAreCopyOnWrite()); return true; } @@ -3661,7 +3662,7 @@ MObjectState::MObjectState(MDefinition *obj) if (obj->isNewObject()) templateObject = obj->toNewObject()->templateObject(); else if (obj->isCreateThisWithTemplate()) - templateObject = obj->toCreateThisWithTemplate()->templateObject(); + templateObject = &obj->toCreateThisWithTemplate()->templateObject()->as(); else templateObject = obj->toNewCallObject()->templateObject(); numSlots_ = templateObject->slotSpan(); @@ -4727,10 +4728,12 @@ AddTypeGuard(TempAllocator &alloc, MBasicBlock *current, MDefinition *obj, { MInstruction *guard; - if (type->isTypeObject()) - guard = MGuardObjectType::New(alloc, obj, type->asTypeObject(), bailOnEquality); - else + if (type->isTypeObject()) { + guard = MGuardObjectType::New(alloc, obj, type->asTypeObject(), bailOnEquality, + Bailout_ObjectIdentityOrTypeGuard); + } else { guard = MGuardObjectIdentity::New(alloc, obj, type->asSingleObject(), bailOnEquality); + } current->add(guard); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 407d754102b5..fe76bc158385 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -4273,8 +4273,8 @@ class MCreateThisWithTemplate } // Template for |this|, provided by TI. - PlainObject *templateObject() const { - return &getOperand(0)->toConstant()->value().toObject().as(); + JSObject *templateObject() const { + return &getOperand(0)->toConstant()->value().toObject(); } gc::InitialHeap initialHeap() const { @@ -8059,21 +8059,29 @@ class MLoadUnboxedObjectOrNull : public MBinaryInstruction, public SingleObjectPolicy::Data { - bool bailOnNull_; + public: + enum NullBehavior { + HandleNull, + BailOnNull, + NullNotPossible + }; + + private: + NullBehavior nullBehavior_; int32_t offsetAdjustment_; MLoadUnboxedObjectOrNull(MDefinition *elements, MDefinition *index, - bool bailOnNull, int32_t offsetAdjustment) + NullBehavior nullBehavior, int32_t offsetAdjustment) : MBinaryInstruction(elements, index), - bailOnNull_(bailOnNull), + nullBehavior_(nullBehavior), offsetAdjustment_(offsetAdjustment) { - if (bailOnNull) { + if (nullBehavior == BailOnNull) { // Don't eliminate loads which bail out on a null pointer, for the // same reason as MLoadElement. setGuard(); } - setResultType(bailOnNull ? MIRType_Object : MIRType_Value); + setResultType(nullBehavior == HandleNull ? MIRType_Value : MIRType_Object); setMovable(); MOZ_ASSERT(IsValidElementsType(elements, offsetAdjustment)); MOZ_ASSERT(index->type() == MIRType_Int32); @@ -8084,8 +8092,9 @@ class MLoadUnboxedObjectOrNull static MLoadUnboxedObjectOrNull *New(TempAllocator &alloc, MDefinition *elements, MDefinition *index, - bool bailOnNull, int32_t offsetAdjustment) { - return new(alloc) MLoadUnboxedObjectOrNull(elements, index, bailOnNull, offsetAdjustment); + NullBehavior nullBehavior, int32_t offsetAdjustment) { + return new(alloc) MLoadUnboxedObjectOrNull(elements, index, nullBehavior, + offsetAdjustment); } MDefinition *elements() const { @@ -8094,20 +8103,20 @@ class MLoadUnboxedObjectOrNull MDefinition *index() const { return getOperand(1); } - bool bailOnNull() const { - return bailOnNull_; + NullBehavior nullBehavior() const { + return nullBehavior_; } int32_t offsetAdjustment() const { return offsetAdjustment_; } bool fallible() const { - return bailOnNull(); + return nullBehavior() == BailOnNull; } bool congruentTo(const MDefinition *ins) const MOZ_OVERRIDE { if (!ins->isLoadUnboxedObjectOrNull()) return false; const MLoadUnboxedObjectOrNull *other = ins->toLoadUnboxedObjectOrNull(); - if (bailOnNull() != other->bailOnNull()) + if (nullBehavior() != other->nullBehavior()) return false; if (offsetAdjustment() != other->offsetAdjustment()) return false; @@ -8140,7 +8149,8 @@ class MLoadUnboxedString INSTRUCTION_HEADER(LoadUnboxedString) static MLoadUnboxedString *New(TempAllocator &alloc, - MDefinition *elements, MDefinition *index, int32_t offsetAdjustment) { + MDefinition *elements, MDefinition *index, + int32_t offsetAdjustment = 0) { return new(alloc) MLoadUnboxedString(elements, index, offsetAdjustment); } @@ -8331,7 +8341,7 @@ class MStoreUnboxedObjectOrNull static MStoreUnboxedObjectOrNull *New(TempAllocator &alloc, MDefinition *elements, MDefinition *index, MDefinition *value, MDefinition *typedObj, - int32_t offsetAdjustment) { + int32_t offsetAdjustment = 0) { return new(alloc) MStoreUnboxedObjectOrNull(elements, index, value, typedObj, offsetAdjustment); } @@ -8386,7 +8396,7 @@ class MStoreUnboxedString static MStoreUnboxedString *New(TempAllocator &alloc, MDefinition *elements, MDefinition *index, - MDefinition *value, int32_t offsetAdjustment) { + MDefinition *value, int32_t offsetAdjustment = 0) { return new(alloc) MStoreUnboxedString(elements, index, value, offsetAdjustment); } MDefinition *elements() const { @@ -8581,14 +8591,16 @@ class MLoadTypedArrayElement Scalar::Type arrayType_; bool requiresBarrier_; int32_t offsetAdjustment_; + bool canonicalizeDoubles_; MLoadTypedArrayElement(MDefinition *elements, MDefinition *index, Scalar::Type arrayType, MemoryBarrierRequirement requiresBarrier, - int32_t offsetAdjustment) + int32_t offsetAdjustment, bool canonicalizeDoubles) : MBinaryInstruction(elements, index), arrayType_(arrayType), requiresBarrier_(requiresBarrier == DoesRequireMemoryBarrier), - offsetAdjustment_(offsetAdjustment) + offsetAdjustment_(offsetAdjustment), + canonicalizeDoubles_(canonicalizeDoubles) { setResultType(MIRType_Value); if (requiresBarrier_) @@ -8606,10 +8618,12 @@ class MLoadTypedArrayElement static MLoadTypedArrayElement *New(TempAllocator &alloc, MDefinition *elements, MDefinition *index, Scalar::Type arrayType, MemoryBarrierRequirement requiresBarrier=DoesNotRequireMemoryBarrier, - int32_t offsetAdjustment = 0) + int32_t offsetAdjustment = 0, + bool canonicalizeDoubles = true) { return new(alloc) MLoadTypedArrayElement(elements, index, arrayType, - requiresBarrier, offsetAdjustment); + requiresBarrier, offsetAdjustment, + canonicalizeDoubles); } Scalar::Type arrayType() const { @@ -8622,6 +8636,9 @@ class MLoadTypedArrayElement bool requiresMemoryBarrier() const { return requiresBarrier_; } + bool canonicalizeDoubles() const { + return canonicalizeDoubles_; + } MDefinition *elements() const { return getOperand(0); } @@ -8649,6 +8666,8 @@ class MLoadTypedArrayElement return false; if (offsetAdjustment() != other->offsetAdjustment()) return false; + if (canonicalizeDoubles() != other->canonicalizeDoubles()) + return false; return congruentIfOperandsEqual(other); } @@ -9340,8 +9359,8 @@ class MGetPropertyCache bool updateForReplacement(MDefinition *ins) MOZ_OVERRIDE; }; -// Emit code to load a value from an object's slots if its shape matches -// one of the shapes observed by the baseline IC, else bails out. +// Emit code to load a value from an object if its shape/type matches one of +// the shapes/types observed by the baseline IC, else bails out. class MGetPropertyPolymorphic : public MUnaryInstruction, public SingleObjectPolicy::Data @@ -9354,12 +9373,14 @@ class MGetPropertyPolymorphic Shape *shape; }; - Vector shapes_; + Vector nativeShapes_; + Vector unboxedTypes_; AlwaysTenuredPropertyName name_; MGetPropertyPolymorphic(TempAllocator &alloc, MDefinition *obj, PropertyName *name) : MUnaryInstruction(obj), - shapes_(alloc), + nativeShapes_(alloc), + unboxedTypes_(alloc), name_(name) { setGuard(); @@ -9367,10 +9388,6 @@ class MGetPropertyPolymorphic setResultType(MIRType_Value); } - PropertyName *name() const { - return name_; - } - public: INSTRUCTION_HEADER(GetPropertyPolymorphic) @@ -9390,22 +9407,35 @@ class MGetPropertyPolymorphic Entry entry; entry.objShape = objShape; entry.shape = shape; - return shapes_.append(entry); + return nativeShapes_.append(entry); + } + bool addUnboxedType(types::TypeObject *type) { + return unboxedTypes_.append(type); } size_t numShapes() const { - return shapes_.length(); + return nativeShapes_.length(); } Shape *objShape(size_t i) const { - return shapes_[i].objShape; + return nativeShapes_[i].objShape; } Shape *shape(size_t i) const { - return shapes_[i].shape; + return nativeShapes_[i].shape; + } + size_t numUnboxedTypes() const { + return unboxedTypes_.length(); + } + types::TypeObject *unboxedType(size_t i) const { + return unboxedTypes_[i]; + } + PropertyName *name() const { + return name_; } MDefinition *obj() const { return getOperand(0); } AliasSet getAliasSet() const MOZ_OVERRIDE { - return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | AliasSet::DynamicSlot); + return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | AliasSet::DynamicSlot | + (unboxedTypes_.empty() ? 0 : (AliasSet::TypedArrayElement | AliasSet::Element))); } bool mightAlias(const MDefinition *store) const MOZ_OVERRIDE; @@ -9425,12 +9455,17 @@ class MSetPropertyPolymorphic Shape *shape; }; - Vector shapes_; + Vector nativeShapes_; + Vector unboxedTypes_; + AlwaysTenuredPropertyName name_; bool needsBarrier_; - MSetPropertyPolymorphic(TempAllocator &alloc, MDefinition *obj, MDefinition *value) + MSetPropertyPolymorphic(TempAllocator &alloc, MDefinition *obj, MDefinition *value, + PropertyName *name) : MBinaryInstruction(obj, value), - shapes_(alloc), + nativeShapes_(alloc), + unboxedTypes_(alloc), + name_(name), needsBarrier_(false) { } @@ -9438,24 +9473,37 @@ class MSetPropertyPolymorphic public: INSTRUCTION_HEADER(SetPropertyPolymorphic) - static MSetPropertyPolymorphic *New(TempAllocator &alloc, MDefinition *obj, MDefinition *value) { - return new(alloc) MSetPropertyPolymorphic(alloc, obj, value); + static MSetPropertyPolymorphic *New(TempAllocator &alloc, MDefinition *obj, MDefinition *value, + PropertyName *name) { + return new(alloc) MSetPropertyPolymorphic(alloc, obj, value, name); } bool addShape(Shape *objShape, Shape *shape) { Entry entry; entry.objShape = objShape; entry.shape = shape; - return shapes_.append(entry); + return nativeShapes_.append(entry); + } + bool addUnboxedType(types::TypeObject *type) { + return unboxedTypes_.append(type); } size_t numShapes() const { - return shapes_.length(); + return nativeShapes_.length(); } Shape *objShape(size_t i) const { - return shapes_[i].objShape; + return nativeShapes_[i].objShape; } Shape *shape(size_t i) const { - return shapes_[i].shape; + return nativeShapes_[i].shape; + } + size_t numUnboxedTypes() const { + return unboxedTypes_.length(); + } + types::TypeObject *unboxedType(size_t i) const { + return unboxedTypes_[i]; + } + PropertyName *name() const { + return name_; } MDefinition *obj() const { return getOperand(0); @@ -9470,7 +9518,8 @@ class MSetPropertyPolymorphic needsBarrier_ = true; } AliasSet getAliasSet() const MOZ_OVERRIDE { - return AliasSet::Store(AliasSet::ObjectFields | AliasSet::FixedSlot | AliasSet::DynamicSlot); + return AliasSet::Store(AliasSet::ObjectFields | AliasSet::FixedSlot | AliasSet::DynamicSlot | + (unboxedTypes_.empty() ? 0 : (AliasSet::TypedArrayElement | AliasSet::Element))); } }; @@ -9805,11 +9854,14 @@ class MGuardObjectType { AlwaysTenured typeObject_; bool bailOnEquality_; + BailoutKind bailoutKind_; - MGuardObjectType(MDefinition *obj, types::TypeObject *typeObject, bool bailOnEquality) + MGuardObjectType(MDefinition *obj, types::TypeObject *typeObject, bool bailOnEquality, + BailoutKind bailoutKind) : MUnaryInstruction(obj), typeObject_(typeObject), - bailOnEquality_(bailOnEquality) + bailOnEquality_(bailOnEquality), + bailoutKind_(bailoutKind) { setGuard(); setMovable(); @@ -9820,8 +9872,8 @@ class MGuardObjectType INSTRUCTION_HEADER(GuardObjectType) static MGuardObjectType *New(TempAllocator &alloc, MDefinition *obj, types::TypeObject *typeObject, - bool bailOnEquality) { - return new(alloc) MGuardObjectType(obj, typeObject, bailOnEquality); + bool bailOnEquality, BailoutKind bailoutKind) { + return new(alloc) MGuardObjectType(obj, typeObject, bailOnEquality, bailoutKind); } MDefinition *obj() const { @@ -9833,6 +9885,9 @@ class MGuardObjectType bool bailOnEquality() const { return bailOnEquality_; } + BailoutKind bailoutKind() const { + return bailoutKind_; + } bool congruentTo(const MDefinition *ins) const MOZ_OVERRIDE { if (!ins->isGuardObjectType()) return false; @@ -9840,6 +9895,8 @@ class MGuardObjectType return false; if (bailOnEquality() != ins->toGuardObjectType()->bailOnEquality()) return false; + if (bailoutKind() != ins->toGuardObjectType()->bailoutKind()) + return false; return congruentIfOperandsEqual(ins); } AliasSet getAliasSet() const MOZ_OVERRIDE { diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index 4e0718df9f50..f7c96b310958 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -306,7 +306,7 @@ MacroAssembler::storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister val template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const T &src, AnyRegister dest, Register temp, - Label *fail) + Label *fail, bool canonicalizeDoubles) { switch (arrayType) { case Scalar::Int8: @@ -344,7 +344,8 @@ MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const T &src, AnyRegi break; case Scalar::Float64: loadDouble(src, dest.fpu()); - canonicalizeDouble(dest.fpu()); + if (canonicalizeDoubles) + canonicalizeDouble(dest.fpu()); break; default: MOZ_CRASH("Invalid typed array type"); @@ -352,9 +353,9 @@ MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const T &src, AnyRegi } template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const Address &src, AnyRegister dest, - Register temp, Label *fail); + Register temp, Label *fail, bool canonicalizeDoubles); template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const BaseIndex &src, AnyRegister dest, - Register temp, Label *fail); + Register temp, Label *fail, bool canonicalizeDoubles); template void @@ -621,6 +622,214 @@ MacroAssembler::atomicBinopToTypedIntArray(AtomicOp op, Scalar::Type arrayType, const Register &value, const BaseIndex &mem, Register temp1, Register temp2, AnyRegister output); +template +void +MacroAssembler::loadUnboxedProperty(T address, JSValueType type, TypedOrValueRegister output) +{ + switch (type) { + case JSVAL_TYPE_BOOLEAN: + case JSVAL_TYPE_INT32: + case JSVAL_TYPE_STRING: { + Register outReg; + if (output.hasValue()) { + outReg = output.valueReg().scratchReg(); + } else { + MOZ_ASSERT(output.type() == MIRTypeFromValueType(type)); + outReg = output.typedReg().gpr(); + } + + switch (type) { + case JSVAL_TYPE_BOOLEAN: + load8ZeroExtend(address, outReg); + break; + case JSVAL_TYPE_INT32: + load32(address, outReg); + break; + case JSVAL_TYPE_STRING: + loadPtr(address, outReg); + break; + default: + MOZ_CRASH(); + } + + if (output.hasValue()) + tagValue(type, outReg, output.valueReg()); + break; + } + + case JSVAL_TYPE_OBJECT: + if (output.hasValue()) { + Register scratch = output.valueReg().scratchReg(); + loadPtr(address, scratch); + + Label notNull, done; + branchPtr(Assembler::NotEqual, scratch, ImmWord(0), ¬Null); + + moveValue(NullValue(), output.valueReg()); + jump(&done); + + bind(¬Null); + tagValue(JSVAL_TYPE_OBJECT, scratch, output.valueReg()); + + bind(&done); + } else { + // Reading null can't be possible here, as otherwise the result + // would be a value (either because null has been read before or + // because there is a barrier). + Register reg = output.typedReg().gpr(); + loadPtr(address, reg); +#ifdef DEBUG + Label ok; + branchTestPtr(Assembler::NonZero, reg, reg, &ok); + assumeUnreachable("Null not possible"); + bind(&ok); +#endif + } + break; + + case JSVAL_TYPE_DOUBLE: + // Note: doubles in unboxed objects are not accessed through other + // views and do not need canonicalization. + if (output.hasValue()) + loadValue(address, output.valueReg()); + else + loadDouble(address, output.typedReg().fpu()); + break; + + default: + MOZ_CRASH(); + } +} + +template void +MacroAssembler::loadUnboxedProperty(Address address, JSValueType type, + TypedOrValueRegister output); + +template void +MacroAssembler::loadUnboxedProperty(BaseIndex address, JSValueType type, + TypedOrValueRegister output); + +template +void +MacroAssembler::storeUnboxedProperty(T address, JSValueType type, + ConstantOrRegister value, Label *failure) +{ + switch (type) { + case JSVAL_TYPE_BOOLEAN: + if (value.constant()) { + if (value.value().isBoolean()) + store8(Imm32(value.value().toBoolean()), address); + else + jump(failure); + } else if (value.reg().hasTyped()) { + if (value.reg().type() == MIRType_Boolean) + store8(value.reg().typedReg().gpr(), address); + else + jump(failure); + } else { + if (failure) + branchTestBoolean(Assembler::NotEqual, value.reg().valueReg(), failure); + storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ 1); + } + break; + + case JSVAL_TYPE_INT32: + if (value.constant()) { + if (value.value().isInt32()) + store32(Imm32(value.value().toInt32()), address); + else + jump(failure); + } else if (value.reg().hasTyped()) { + if (value.reg().type() == MIRType_Int32) + store32(value.reg().typedReg().gpr(), address); + else + jump(failure); + } else { + if (failure) + branchTestInt32(Assembler::NotEqual, value.reg().valueReg(), failure); + storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ 4); + } + break; + + case JSVAL_TYPE_DOUBLE: + if (value.constant()) { + if (value.value().isNumber()) { + loadConstantDouble(value.value().toNumber(), ScratchDoubleReg); + storeDouble(ScratchDoubleReg, address); + } else { + jump(failure); + } + } else if (value.reg().hasTyped()) { + if (value.reg().type() == MIRType_Int32) { + convertInt32ToDouble(value.reg().typedReg().gpr(), ScratchDoubleReg); + storeDouble(ScratchDoubleReg, address); + } else if (value.reg().type() == MIRType_Double) { + storeDouble(value.reg().typedReg().fpu(), address); + } else { + jump(failure); + } + } else { + if (failure) + branchTestNumber(Assembler::NotEqual, value.reg().valueReg(), failure); + unboxValue(value.reg().valueReg(), AnyRegister(ScratchDoubleReg)); + storeDouble(ScratchDoubleReg, address); + } + break; + + case JSVAL_TYPE_OBJECT: + if (value.constant()) { + if (value.value().isObjectOrNull()) + storePtr(ImmGCPtr(value.value().toObjectOrNull()), address); + else + jump(failure); + } else if (value.reg().hasTyped()) { + MOZ_ASSERT(value.reg().type() != MIRType_Null); + if (value.reg().type() == MIRType_Object) + storePtr(value.reg().typedReg().gpr(), address); + else + jump(failure); + } else { + if (failure) { + Label ok; + branchTestNull(Assembler::Equal, value.reg().valueReg(), &ok); + branchTestObject(Assembler::NotEqual, value.reg().valueReg(), failure); + bind(&ok); + } + storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ sizeof(uintptr_t)); + } + break; + + case JSVAL_TYPE_STRING: + if (value.constant()) { + if (value.value().isString()) + storePtr(ImmGCPtr(value.value().toString()), address); + else + jump(failure); + } else if (value.reg().hasTyped()) { + if (value.reg().type() == MIRType_String) + storePtr(value.reg().typedReg().gpr(), address); + else + jump(failure); + } else { + if (failure) + branchTestString(Assembler::NotEqual, value.reg().valueReg(), failure); + storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ sizeof(uintptr_t)); + } + break; + + default: + MOZ_CRASH(); + } +} + +template void +MacroAssembler::storeUnboxedProperty(Address address, JSValueType type, + ConstantOrRegister value, Label *failure); + +template void +MacroAssembler::storeUnboxedProperty(BaseIndex address, JSValueType type, + ConstantOrRegister value, Label *failure); + // Inlined version of gc::CheckAllocatorState that checks the bare essentials // and bails for anything that cannot be handled with our jit allocators. void @@ -780,22 +989,22 @@ MacroAssembler::allocateObject(Register result, Register slots, gc::AllocKind al callFreeStub(slots); jump(fail); - bind(&success); + breakpoint(); } void -MacroAssembler::newGCThing(Register result, Register temp, NativeObject *templateObj, - gc::InitialHeap initialHeap, Label *fail) +MacroAssembler::newGCThing(Register result, Register temp, JSObject *templateObj, + gc::InitialHeap initialHeap, Label *fail) { // This method does not initialize the object: if external slots get // allocated into |temp|, there is no easy way for us to ensure the caller // frees them. Instead just assert this case does not happen. - MOZ_ASSERT(!templateObj->numDynamicSlots()); + MOZ_ASSERT_IF(templateObj->isNative(), !templateObj->as().numDynamicSlots()); gc::AllocKind allocKind = templateObj->asTenured().getAllocKind(); MOZ_ASSERT(allocKind >= gc::FINALIZE_OBJECT0 && allocKind <= gc::FINALIZE_OBJECT_LAST); - allocateObject(result, temp, allocKind, templateObj->numDynamicSlots(), initialHeap, fail); + allocateObject(result, temp, allocKind, 0, initialHeap, fail); } void @@ -1030,18 +1239,37 @@ MacroAssembler::initGCThing(Register obj, Register slots, JSObject *templateObj, } } } else if (templateObj->is()) { - InlineTypedObject *ntemplate = &templateObj->as(); + size_t nbytes = templateObj->as().size(); + const uint8_t *memory = templateObj->as().inlineTypedMem(); // Memcpy the contents of the template object to the new object. - size_t nbytes = ntemplate->size(); size_t offset = 0; while (nbytes) { - uintptr_t value = *(uintptr_t *)(ntemplate->inlineTypedMem() + offset); + uintptr_t value = *(uintptr_t *)(memory + offset); storePtr(ImmWord(value), Address(obj, InlineTypedObject::offsetOfDataStart() + offset)); nbytes = (nbytes < sizeof(uintptr_t)) ? 0 : nbytes - sizeof(uintptr_t); offset += sizeof(uintptr_t); } + } else if (templateObj->is()) { + const UnboxedLayout &layout = templateObj->as().layout(); + + // Initialize reference fields of the object, per UnboxedPlainObject::create. + if (const int32_t *list = layout.traceList()) { + while (*list != -1) { + storePtr(ImmGCPtr(GetJitContext()->runtime->names().empty), + Address(obj, UnboxedPlainObject::offsetOfData() + *list)); + list++; + } + list++; + while (*list != -1) { + storePtr(ImmWord(0), + Address(obj, UnboxedPlainObject::offsetOfData() + *list)); + list++; + } + // Unboxed objects don't have Values to initialize. + MOZ_ASSERT(*(list + 1) == -1); + } } else { MOZ_CRASH("Unknown object"); } diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 5b6133724396..7638f2b71d23 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -694,7 +694,8 @@ class MacroAssembler : public MacroAssemblerSpecific } template - void loadFromTypedArray(Scalar::Type arrayType, const T &src, AnyRegister dest, Register temp, Label *fail); + void loadFromTypedArray(Scalar::Type arrayType, const T &src, AnyRegister dest, Register temp, Label *fail, + bool canonicalizeDoubles = true); template void loadFromTypedArray(Scalar::Type arrayType, const T &src, const ValueOperand &dest, bool allowDouble, @@ -732,6 +733,17 @@ class MacroAssembler : public MacroAssemblerSpecific void storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, const BaseIndex &dest); void storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, const Address &dest); + // Load a property from an UnboxedPlainObject. + template + void loadUnboxedProperty(T address, JSValueType type, TypedOrValueRegister output); + + // Store a property to an UnboxedPlainObject, without triggering barriers. + // If failure is null, the value definitely has a type suitable for storing + // in the property. + template + void storeUnboxedProperty(T address, JSValueType type, + ConstantOrRegister value, Label *failure); + Register extractString(const Address &address, Register scratch) { return extractObject(address, scratch); } @@ -804,7 +816,7 @@ class MacroAssembler : public MacroAssemblerSpecific void createGCObject(Register result, Register temp, JSObject *templateObj, gc::InitialHeap initialHeap, Label *fail, bool initFixedSlots = true); - void newGCThing(Register result, Register temp, NativeObject *templateObj, + void newGCThing(Register result, Register temp, JSObject *templateObj, gc::InitialHeap initialHeap, Label *fail); void initGCThing(Register obj, Register temp, JSObject *templateObj, bool initFixedSlots = true); diff --git a/js/src/jit/OptimizationTracking.h b/js/src/jit/OptimizationTracking.h index 3ad208cc6c3e..0a31f55b54eb 100644 --- a/js/src/jit/OptimizationTracking.h +++ b/js/src/jit/OptimizationTracking.h @@ -32,6 +32,8 @@ namespace jit { "getprop TypedObject") \ _(GetProp_DefiniteSlot, \ "getprop definite slot") \ + _(GetProp_Unboxed, \ + "getprop unboxed object") \ _(GetProp_CommonGetter, \ "getprop common getter") \ _(GetProp_InlineAccess, \ @@ -47,6 +49,8 @@ namespace jit { "setprop TypedObject") \ _(SetProp_DefiniteSlot, \ "setprop definite slot") \ + _(SetProp_Unboxed, \ + "setprop unboxed object") \ _(SetProp_InlineAccess, \ "setprop inline access") \ \ @@ -108,12 +112,20 @@ namespace jit { "is not singleton") \ _(NotFixedSlot, \ "property not in fixed slot") \ + _(InconsistentFixedSlot, \ + "property not in a consistent fixed slot") \ _(NotObject, \ "not definitely an object") \ _(NotStruct, \ "not definitely a TypedObject struct") \ + _(NotUnboxed, \ + "not definitely an unboxed object") \ _(StructNoField, \ "struct doesn't definitely have field") \ + _(InconsistentFieldType, \ + "unboxed property does not consistent type") \ + _(InconsistentFieldOffset, \ + "unboxed property does not consistent offset") \ _(NeedsTypeBarrier, \ "needs type barrier") \ _(InDictionaryMode, \ diff --git a/js/src/jit/ScalarReplacement.cpp b/js/src/jit/ScalarReplacement.cpp index c96ba425751b..61bbfe36b384 100644 --- a/js/src/jit/ScalarReplacement.cpp +++ b/js/src/jit/ScalarReplacement.cpp @@ -112,6 +112,10 @@ IsObjectEscaped(MInstruction *ins, JSObject *objDefault = nullptr) else obj = objDefault; + // Don't optimize unboxed objects, which aren't handled by MObjectState. + if (obj->is()) + return true; + // Check if the object is escaped. If the object is not the first argument // of either a known Store / Load, then we consider it as escaped. This is a // cheap and conservative escape analysis. diff --git a/js/src/jit/arm/Lowering-arm.cpp b/js/src/jit/arm/Lowering-arm.cpp index 5b756d95ddaa..809ebbcfc85b 100644 --- a/js/src/jit/arm/Lowering-arm.cpp +++ b/js/src/jit/arm/Lowering-arm.cpp @@ -393,7 +393,7 @@ LIRGeneratorARM::visitGuardObjectType(MGuardObjectType *ins) LDefinition tempObj = temp(LDefinition::OBJECT); LGuardObjectType *guard = new(alloc()) LGuardObjectType(useRegister(ins->obj()), tempObj); - assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard); + assignSnapshot(guard, ins->bailoutKind()); add(guard, ins); redefine(ins, ins->obj()); } diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index e1cc282edeb2..8cafc03dfb81 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -2685,6 +2685,20 @@ MacroAssemblerARMCompat::cmpPtr(const Address &lhs, ImmPtr rhs) cmpPtr(lhs, ImmWord(uintptr_t(rhs.value))); } +void +MacroAssemblerARMCompat::cmpPtr(const Address &lhs, ImmGCPtr rhs) +{ + loadPtr(lhs, secondScratchReg_); + ma_cmp(secondScratchReg_, rhs); +} + +void +MacroAssemblerARMCompat::cmpPtr(const Address &lhs, Imm32 rhs) +{ + loadPtr(lhs, secondScratchReg_); + ma_cmp(secondScratchReg_, rhs); +} + void MacroAssemblerARMCompat::setStackArg(Register reg, uint32_t arg) { diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 8b136666e6bb..83f246137c0b 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -1129,6 +1129,19 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const T &dest, MIRType slotType); + template + void storeUnboxedPayload(ValueOperand value, T address, size_t nbytes) { + switch (nbytes) { + case 4: + storePtr(value.payloadReg(), address); + return; + case 1: + store8(value.payloadReg(), address); + return; + default: MOZ_CRASH("Bad payload width"); + } + } + void moveValue(const Value &val, const ValueOperand &dest); void moveValue(const ValueOperand &src, const ValueOperand &dest) { @@ -1622,14 +1635,16 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void cmp32(const Operand &lhs, Imm32 rhs); void cmp32(const Operand &lhs, Register rhs); + void cmpPtr(Register lhs, Register rhs); void cmpPtr(Register lhs, ImmWord rhs); void cmpPtr(Register lhs, ImmPtr rhs); - void cmpPtr(Register lhs, Register rhs); void cmpPtr(Register lhs, ImmGCPtr rhs); void cmpPtr(Register lhs, Imm32 rhs); void cmpPtr(const Address &lhs, Register rhs); void cmpPtr(const Address &lhs, ImmWord rhs); void cmpPtr(const Address &lhs, ImmPtr rhs); + void cmpPtr(const Address &lhs, ImmGCPtr rhs); + void cmpPtr(const Address &lhs, Imm32 rhs); void subPtr(Imm32 imm, const Register dest); void subPtr(const Address &addr, const Register dest); diff --git a/js/src/jit/mips/Lowering-mips.cpp b/js/src/jit/mips/Lowering-mips.cpp index da72fa305b44..93b020f544b5 100644 --- a/js/src/jit/mips/Lowering-mips.cpp +++ b/js/src/jit/mips/Lowering-mips.cpp @@ -384,7 +384,7 @@ LIRGeneratorMIPS::visitGuardObjectType(MGuardObjectType *ins) LDefinition tempObj = temp(LDefinition::OBJECT); LGuardObjectType *guard = new(alloc()) LGuardObjectType(useRegister(ins->obj()), tempObj); - assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard); + assignSnapshot(guard, ins->bailoutKind()); add(guard, ins); redefine(ins, ins->obj()); } diff --git a/js/src/jit/mips/MacroAssembler-mips.h b/js/src/jit/mips/MacroAssembler-mips.h index 3b329f2dd264..24e591272afb 100644 --- a/js/src/jit/mips/MacroAssembler-mips.h +++ b/js/src/jit/mips/MacroAssembler-mips.h @@ -869,6 +869,19 @@ public: void storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const T &dest, MIRType slotType); + template + void storeUnboxedPayload(ValueOperand value, T address, size_t nbytes) { + switch (nbytes) { + case 4: + storePtr(value.payloadReg(), address); + return; + case 1: + store8(value.payloadReg(), address); + return; + default: MOZ_CRASH("Bad payload width"); + } + } + void moveValue(const Value &val, const ValueOperand &dest); void moveValue(const ValueOperand &src, const ValueOperand &dest) { diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index bc847e82cf1a..aaa646d0cc02 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -400,6 +400,7 @@ class MacroAssemblerNone : public Assembler template void loadUnboxedValue(T, MIRType, AnyRegister) { MOZ_CRASH(); } template void storeUnboxedValue(ConstantOrRegister, MIRType, T, MIRType) { MOZ_CRASH(); } + template void storeUnboxedPayload(ValueOperand value, T, size_t) { MOZ_CRASH(); } void rshiftPtr(Imm32, Register) { MOZ_CRASH(); } void rshiftPtrArithmetic(Imm32, Register) { MOZ_CRASH(); } diff --git a/js/src/jit/shared/Lowering-x86-shared.cpp b/js/src/jit/shared/Lowering-x86-shared.cpp index 0e1178443f11..0476944b67e6 100644 --- a/js/src/jit/shared/Lowering-x86-shared.cpp +++ b/js/src/jit/shared/Lowering-x86-shared.cpp @@ -49,7 +49,7 @@ LIRGeneratorX86Shared::visitGuardObjectType(MGuardObjectType *ins) MOZ_ASSERT(ins->obj()->type() == MIRType_Object); LGuardObjectType *guard = new(alloc()) LGuardObjectType(useRegisterAtStart(ins->obj())); - assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard); + assignSnapshot(guard, ins->bailoutKind()); add(guard, ins); redefine(ins, ins->obj()); } diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 5083523cecc0..f7fa5de20891 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -1342,6 +1342,23 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared template void storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const T &dest, MIRType slotType); + template + void storeUnboxedPayload(ValueOperand value, T address, size_t nbytes) { + switch (nbytes) { + case 8: + unboxNonDouble(value, ScratchReg); + storePtr(ScratchReg, address); + return; + case 4: + store32(value.valueReg(), address); + return; + case 1: + store8(value.valueReg(), address); + return; + default: MOZ_CRASH("Bad payload width"); + } + } + void loadInstructionPointerAfterCall(Register dest) { loadPtr(Address(StackPointer, 0x0), dest); } diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 25be7bef55f2..bf65eae5c4c9 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -550,6 +550,9 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared void cmpPtr(const Address &lhs, const ImmPtr rhs) { cmpPtr(lhs, ImmWord(uintptr_t(rhs.value))); } + void cmpPtr(const Address &lhs, const ImmGCPtr rhs) { + cmpPtr(Operand(lhs), rhs); + } void cmpPtr(Register lhs, Register rhs) { cmp32(lhs, rhs); } @@ -1065,6 +1068,19 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared void storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const T &dest, MIRType slotType); + template + void storeUnboxedPayload(ValueOperand value, T address, size_t nbytes) { + switch (nbytes) { + case 4: + storePtr(value.payloadReg(), address); + return; + case 1: + store8(value.payloadReg(), address); + return; + default: MOZ_CRASH("Bad payload width"); + } + } + void rshiftPtr(Imm32 imm, Register dest) { shrl(imm, dest); } From 98610dedd6b61aed09908f0cafe0225e24503aca Mon Sep 17 00:00:00 2001 From: Chris Pearce Date: Mon, 2 Feb 2015 09:28:41 +1300 Subject: [PATCH 03/16] Bug 1127641 - Reduce MDSM video frame queue length when hardware accelerated. r=kentuckyfriedtakahe --- dom/media/MediaDecoderStateMachine.cpp | 37 ++++++++++++++++++---- dom/media/MediaInfo.h | 3 ++ dom/media/fmp4/MP4Reader.cpp | 1 + dom/media/fmp4/PlatformDecoderModule.h | 1 + dom/media/fmp4/SharedDecoderManager.cpp | 7 ++++ dom/media/fmp4/SharedDecoderManager.h | 1 + dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp | 5 +++ dom/media/fmp4/wmf/WMFMediaDataDecoder.h | 4 +++ dom/media/fmp4/wmf/WMFVideoMFTManager.cpp | 6 ++++ dom/media/fmp4/wmf/WMFVideoMFTManager.h | 2 ++ 10 files changed, 61 insertions(+), 6 deletions(-) diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index 98d2a557540e..d7d8497ed7d8 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -191,6 +191,12 @@ static int64_t DurationToUsecs(TimeDuration aDuration) { return static_cast(aDuration.ToSeconds() * USECS_PER_S); } +static const uint32_t MIN_VIDEO_QUEUE_SIZE = 3; +static const uint32_t MAX_VIDEO_QUEUE_SIZE = 10; + +static uint32_t sVideoQueueDefaultSize = MAX_VIDEO_QUEUE_SIZE; +static uint32_t sVideoQueueHWAccelSize = MIN_VIDEO_QUEUE_SIZE; + MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder, MediaDecoderReader* aReader, bool aRealTime) : @@ -216,7 +222,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder, mVolume(1.0), mPlaybackRate(1.0), mPreservesPitch(true), - mAmpleVideoFrames(2), + mAmpleVideoFrames(MIN_VIDEO_QUEUE_SIZE), mLowAudioThresholdUsecs(detail::LOW_AUDIO_USECS), mAmpleAudioThresholdUsecs(detail::AMPLE_AUDIO_USECS), mQuickBufferingLowDataThresholdUsecs(detail::QUICK_BUFFERING_LOW_DATA_USECS), @@ -247,8 +253,16 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder, MOZ_COUNT_CTOR(MediaDecoderStateMachine); NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); - mAmpleVideoFrames = - std::max(Preferences::GetUint("media.video-queue.default-size", 10), 3); + static bool sPrefCacheInit = false; + if (!sPrefCacheInit) { + sPrefCacheInit = true; + Preferences::AddUintVarCache(&sVideoQueueDefaultSize, + "media.video-queue.default-size", + MAX_VIDEO_QUEUE_SIZE); + Preferences::AddUintVarCache(&sVideoQueueHWAccelSize, + "media.video-queue.hw-accel-size", + MIN_VIDEO_QUEUE_SIZE); + } mBufferingWait = IsRealTime() ? 0 : 30; mLowDataThresholdUsecs = IsRealTime() ? 0 : detail::LOW_DATA_THRESHOLD_USECS; @@ -2215,16 +2229,27 @@ nsresult MediaDecoderStateMachine::DecodeMetadata() return NS_OK; } + if (NS_FAILED(res) || (!info.HasValidMedia())) { + DECODER_WARN("ReadMetadata failed, res=%x HasValidMedia=%d", res, info.HasValidMedia()); + return NS_ERROR_FAILURE; + } + if (NS_SUCCEEDED(res)) { mDecoder->SetMediaSeekable(mReader->IsMediaSeekable()); } mInfo = info; - if (NS_FAILED(res) || (!info.HasValidMedia())) { - DECODER_WARN("ReadMetadata failed, res=%x HasValidMedia=%d", res, info.HasValidMedia()); - return NS_ERROR_FAILURE; + if (HasVideo()) { + mAmpleVideoFrames = (mReader->IsAsync() && mInfo.mVideo.mIsHardwareAccelerated) + ? std::max(sVideoQueueHWAccelSize, MIN_VIDEO_QUEUE_SIZE) + : std::max(sVideoQueueDefaultSize, MIN_VIDEO_QUEUE_SIZE); + DECODER_LOG("Video decode isAsync=%d HWAccel=%d videoQueueSize=%d", + mReader->IsAsync(), + mInfo.mVideo.mIsHardwareAccelerated, + mAmpleVideoFrames); } + mDecoder->StartProgressUpdates(); mGotDurationFromMetaData = (GetDuration() != -1) || mDurationSet; diff --git a/dom/media/MediaInfo.h b/dom/media/MediaInfo.h index 09104b34bc56..37a280c43edc 100644 --- a/dom/media/MediaInfo.h +++ b/dom/media/MediaInfo.h @@ -41,6 +41,7 @@ public: : mDisplay(0,0) , mStereoMode(StereoMode::MONO) , mHasVideo(false) + , mIsHardwareAccelerated(false) { // TODO: TrackInfo should be initialized by its specific codec decoder. // This following call should be removed once we have that implemented. @@ -59,6 +60,8 @@ public: bool mHasVideo; TrackInfo mTrackInfo; + + bool mIsHardwareAccelerated; }; class AudioInfo { diff --git a/dom/media/fmp4/MP4Reader.cpp b/dom/media/fmp4/MP4Reader.cpp index c72374983033..b77e014f82b5 100644 --- a/dom/media/fmp4/MP4Reader.cpp +++ b/dom/media/fmp4/MP4Reader.cpp @@ -465,6 +465,7 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo, NS_ENSURE_TRUE(mVideo.mDecoder != nullptr, NS_ERROR_FAILURE); nsresult rv = mVideo.mDecoder->Init(); NS_ENSURE_SUCCESS(rv, rv); + mInfo.mVideo.mIsHardwareAccelerated = mVideo.mDecoder->IsHardwareAccelerated(); } // Get the duration, and report it to the decoder if we have it. diff --git a/dom/media/fmp4/PlatformDecoderModule.h b/dom/media/fmp4/PlatformDecoderModule.h index 56edfc67ef99..0f5366c53449 100644 --- a/dom/media/fmp4/PlatformDecoderModule.h +++ b/dom/media/fmp4/PlatformDecoderModule.h @@ -245,6 +245,7 @@ public: virtual void AllocateMediaResources() {} virtual void ReleaseMediaResources() {} virtual void ReleaseDecoder() {} + virtual bool IsHardwareAccelerated() const { return false; } }; } // namespace mozilla diff --git a/dom/media/fmp4/SharedDecoderManager.cpp b/dom/media/fmp4/SharedDecoderManager.cpp index 915fb11ff328..f78bb963d1d2 100644 --- a/dom/media/fmp4/SharedDecoderManager.cpp +++ b/dom/media/fmp4/SharedDecoderManager.cpp @@ -237,4 +237,11 @@ SharedDecoderProxy::ReleaseDecoder() mManager->mDecoder->ReleaseMediaResources(); } } + +bool +SharedDecoderProxy::IsHardwareAccelerated() const +{ + return mManager->mDecoder->IsHardwareAccelerated(); +} + } diff --git a/dom/media/fmp4/SharedDecoderManager.h b/dom/media/fmp4/SharedDecoderManager.h index 0acd7ee8fff8..6433461576ce 100644 --- a/dom/media/fmp4/SharedDecoderManager.h +++ b/dom/media/fmp4/SharedDecoderManager.h @@ -70,6 +70,7 @@ public: virtual bool IsDormantNeeded() MOZ_OVERRIDE; virtual void ReleaseMediaResources() MOZ_OVERRIDE; virtual void ReleaseDecoder() MOZ_OVERRIDE; + virtual bool IsHardwareAccelerated() const MOZ_OVERRIDE; friend class SharedDecoderManager; diff --git a/dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp b/dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp index eb0dcafdd959..8d89c1d699c9 100644 --- a/dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp +++ b/dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp @@ -179,4 +179,9 @@ WMFMediaDataDecoder::ReleaseDecoder() ReleaseMediaResources(); } +bool +WMFMediaDataDecoder::IsHardwareAccelerated() const { + return mMFTManager && mMFTManager->IsHardwareAccelerated(); +} + } // namespace mozilla diff --git a/dom/media/fmp4/wmf/WMFMediaDataDecoder.h b/dom/media/fmp4/wmf/WMFMediaDataDecoder.h index 351ce144685c..0d6424ab39ea 100644 --- a/dom/media/fmp4/wmf/WMFMediaDataDecoder.h +++ b/dom/media/fmp4/wmf/WMFMediaDataDecoder.h @@ -46,6 +46,9 @@ public: // Destroys all resources. virtual void Shutdown() = 0; + + virtual bool IsHardwareAccelerated() const { return false; } + }; // Decodes audio and video using Windows Media Foundation. Samples are decoded @@ -75,6 +78,7 @@ public: virtual void AllocateMediaResources() MOZ_OVERRIDE; virtual void ReleaseMediaResources() MOZ_OVERRIDE; virtual void ReleaseDecoder() MOZ_OVERRIDE; + virtual bool IsHardwareAccelerated() const MOZ_OVERRIDE; private: diff --git a/dom/media/fmp4/wmf/WMFVideoMFTManager.cpp b/dom/media/fmp4/wmf/WMFVideoMFTManager.cpp index dbd07f2bbe30..366d127a22a1 100644 --- a/dom/media/fmp4/wmf/WMFVideoMFTManager.cpp +++ b/dom/media/fmp4/wmf/WMFVideoMFTManager.cpp @@ -495,4 +495,10 @@ WMFVideoMFTManager::Shutdown() DeleteOnMainThread(mDXVA2Manager); } +bool +WMFVideoMFTManager::IsHardwareAccelerated() const +{ + return mUseHwAccel; +} + } // namespace mozilla diff --git a/dom/media/fmp4/wmf/WMFVideoMFTManager.h b/dom/media/fmp4/wmf/WMFVideoMFTManager.h index 3594666eae3f..0b61ba58684f 100644 --- a/dom/media/fmp4/wmf/WMFVideoMFTManager.h +++ b/dom/media/fmp4/wmf/WMFVideoMFTManager.h @@ -35,6 +35,8 @@ public: virtual void Shutdown() MOZ_OVERRIDE; + virtual bool IsHardwareAccelerated() const MOZ_OVERRIDE; + private: bool InitializeDXVA(); From 58a982f86b8ac86464ed7d3e875ff9d53d153509 Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Sun, 1 Feb 2015 17:27:31 -0500 Subject: [PATCH 04/16] Bug 1125040: Use LayoutDeviceIntPoint for nsLayoutUtils::GetEventCoordinatesRelativeTo and Touch::mRefPoint r=botond --- accessible/base/nsCoreUtils.cpp | 2 +- dom/base/nsDOMWindowUtils.cpp | 6 +++--- dom/events/Event.cpp | 3 +-- dom/events/Touch.cpp | 13 +++++-------- dom/events/Touch.h | 4 ++-- dom/ipc/TabChild.cpp | 5 ++--- dom/ipc/TabChild.h | 2 +- dom/ipc/TabParent.cpp | 6 +++--- gfx/layers/apz/util/APZCCallbackHelper.cpp | 7 +++---- gfx/layers/apz/util/APZCCallbackHelper.h | 13 +++++++------ layout/base/SelectionCarets.cpp | 4 ++-- layout/base/TouchCaret.cpp | 5 ++--- layout/base/nsLayoutUtils.cpp | 11 ++++++----- layout/base/nsLayoutUtils.h | 7 ++++--- layout/base/nsPresShell.cpp | 10 +++++----- layout/base/nsPresShell.h | 3 ++- layout/forms/nsNumberControlFrame.cpp | 3 +-- layout/forms/nsRangeFrame.cpp | 6 ++---- layout/xul/nsBoxFrame.cpp | 5 +++-- widget/ContentHelper.cpp | 4 +++- widget/InputData.cpp | 2 +- widget/android/AndroidJavaWrappers.cpp | 2 +- widget/android/nsWindow.cpp | 10 +++++----- widget/android/nsWindow.h | 2 +- widget/nsGUIEventIPC.h | 3 +-- widget/windows/nsWindow.cpp | 2 +- 26 files changed, 68 insertions(+), 72 deletions(-) diff --git a/accessible/base/nsCoreUtils.cpp b/accessible/base/nsCoreUtils.cpp index df46f8e3860a..a564f7b65e80 100644 --- a/accessible/base/nsCoreUtils.cpp +++ b/accessible/base/nsCoreUtils.cpp @@ -149,7 +149,7 @@ nsCoreUtils::DispatchTouchEvent(uint32_t aEventType, int32_t aX, int32_t aY, event.time = PR_IntervalNow(); // XXX: Touch has an identifier of -1 to hint that it is synthesized. - nsRefPtr t = new dom::Touch(-1, nsIntPoint(aX, aY), + nsRefPtr t = new dom::Touch(-1, LayoutDeviceIntPoint(aX, aY), nsIntPoint(1, 1), 0.0f, 1.0f); t->SetTarget(aContent); event.touches.AppendElement(t); diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index c78d9d39dc65..638b13eabf63 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -1158,7 +1158,7 @@ nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType, LayoutDeviceIntPoint pt = ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext); nsRefPtr t = new Touch(aIdentifiers[i], - LayoutDeviceIntPoint::ToUntyped(pt), + pt, nsIntPoint(aRxs[i], aRys[i]), aRotationAngles[i], aForces[i]); @@ -3392,8 +3392,8 @@ nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior, // Get the target frame at the client coordinates passed to us nsPoint offset; nsCOMPtr widget = GetWidget(&offset); - nsIntPoint pt = LayoutDeviceIntPoint::ToUntyped( - ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext())); + LayoutDeviceIntPoint pt = + ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext()); nsPoint ptInRoot = nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame); nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot); diff --git a/dom/events/Event.cpp b/dom/events/Event.cpp index eedf5a69fb4b..e7d967814d34 100644 --- a/dom/events/Event.cpp +++ b/dom/events/Event.cpp @@ -966,8 +966,7 @@ Event::GetClientCoords(nsPresContext* aPresContext, return CSSIntPoint(0, 0); } nsPoint pt = - nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, - LayoutDeviceIntPoint::ToUntyped(aPoint), rootFrame); + nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, aPoint, rootFrame); return CSSIntPoint::FromAppUnitsRounded(pt); } diff --git a/dom/events/Touch.cpp b/dom/events/Touch.cpp index 6e2074f204a9..25f5fde37498 100644 --- a/dom/events/Touch.cpp +++ b/dom/events/Touch.cpp @@ -33,7 +33,7 @@ Touch::Touch(EventTarget* aTarget, mPagePoint = CSSIntPoint(aPageX, aPageY); mScreenPoint = nsIntPoint(aScreenX, aScreenY); mClientPoint = CSSIntPoint(aClientX, aClientY); - mRefPoint = nsIntPoint(0, 0); + mRefPoint = LayoutDeviceIntPoint(0, 0); mPointsInitialized = true; mRadius.x = aRadiusX; mRadius.y = aRadiusY; @@ -46,7 +46,7 @@ Touch::Touch(EventTarget* aTarget, } Touch::Touch(int32_t aIdentifier, - nsIntPoint aPoint, + LayoutDeviceIntPoint aPoint, nsIntPoint aRadius, float aRotationAngle, float aForce) @@ -106,13 +106,10 @@ Touch::InitializePoints(nsPresContext* aPresContext, WidgetEvent* aEvent) return; } mClientPoint = Event::GetClientCoords( - aPresContext, aEvent, LayoutDeviceIntPoint::FromUntyped(mRefPoint), - mClientPoint); + aPresContext, aEvent, mRefPoint, mClientPoint); mPagePoint = Event::GetPageCoords( - aPresContext, aEvent, LayoutDeviceIntPoint::FromUntyped(mRefPoint), - mClientPoint); - mScreenPoint = Event::GetScreenCoords(aPresContext, aEvent, - LayoutDeviceIntPoint::FromUntyped(mRefPoint)); + aPresContext, aEvent, mRefPoint, mClientPoint); + mScreenPoint = Event::GetScreenCoords(aPresContext, aEvent, mRefPoint); mPointsInitialized = true; } diff --git a/dom/events/Touch.h b/dom/events/Touch.h index 9710962c4768..1077a7432eaa 100644 --- a/dom/events/Touch.h +++ b/dom/events/Touch.h @@ -40,7 +40,7 @@ public: float aRotationAngle, float aForce); Touch(int32_t aIdentifier, - nsIntPoint aPoint, + LayoutDeviceIntPoint aPoint, nsIntPoint aRadius, float aRotationAngle, float aForce); @@ -73,7 +73,7 @@ public: float Force() const { return mForce; } nsCOMPtr mTarget; - nsIntPoint mRefPoint; + LayoutDeviceIntPoint mRefPoint; bool mChanged; uint32_t mMessage; int32_t mIdentifier; diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index a63543a43276..b8b9581d7f58 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -2302,9 +2302,8 @@ TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent, if (nsIPresShell* shell = document->GetShell()) { if (nsIFrame* rootFrame = shell->GetRootFrame()) { nsTArray targets; - nsIntPoint refPoint(aEvent.refPoint.x, aEvent.refPoint.y); bool waitForRefresh = - PrepareForSetTargetAPZCNotification(aGuid, aInputBlockId, rootFrame, refPoint, &targets); + PrepareForSetTargetAPZCNotification(aGuid, aInputBlockId, rootFrame, aEvent.refPoint, &targets); SendSetTargetAPZCNotification(shell, aInputBlockId, targets, waitForRefresh); } @@ -2541,7 +2540,7 @@ bool TabChild::PrepareForSetTargetAPZCNotification(const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId, nsIFrame* aRootFrame, - const nsIntPoint& aRefPoint, + const LayoutDeviceIntPoint& aRefPoint, nsTArray* aTargets) { ScrollableLayerGuid guid(aGuid.mLayersId, 0, FrameMetrics::NULL_SCROLL_ID); diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 3c066199acc3..5bc18592617e 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -592,7 +592,7 @@ private: bool PrepareForSetTargetAPZCNotification(const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId, nsIFrame* aRootFrame, - const nsIntPoint& aRefPoint, + const LayoutDeviceIntPoint& aRefPoint, nsTArray* aTargets); // Sends a SetTarget notification for APZC, given one or more previous diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index eb157fcf4e13..f247456ba28e 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1085,7 +1085,7 @@ TabParent::MapEventCoordinatesForChildProcess( for (uint32_t i = 0; i < touches.Length(); ++i) { Touch* touch = touches[i]; if (touch) { - touch->mRefPoint += LayoutDeviceIntPoint::ToUntyped(aOffset); + touch->mRefPoint += aOffset; } } } @@ -1731,7 +1731,7 @@ TabParent::GetChildProcessOffset() return offset; } nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, - nsIntPoint(0, 0), + LayoutDeviceIntPoint(0, 0), targetFrame); return LayoutDeviceIntPoint::ToUntyped(LayoutDeviceIntPoint::FromAppUnitsToNearest( @@ -2485,7 +2485,7 @@ TabParent::InjectTouchEvent(const nsAString& aType, presContext->AppUnitsPerDevPixel()); nsRefPtr t = new Touch(aIdentifiers[i], - LayoutDeviceIntPoint::ToUntyped(pt), + pt, nsIntPoint(aRxs[i], aRys[i]), aRotationAngles[i], aForces[i]); diff --git a/gfx/layers/apz/util/APZCCallbackHelper.cpp b/gfx/layers/apz/util/APZCCallbackHelper.cpp index 7db474cd167e..0fd7e3f377d9 100644 --- a/gfx/layers/apz/util/APZCCallbackHelper.cpp +++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp @@ -355,16 +355,15 @@ APZCCallbackHelper::ApplyCallbackTransform(const CSSPoint& aInput, return input; } -nsIntPoint -APZCCallbackHelper::ApplyCallbackTransform(const nsIntPoint& aPoint, +LayoutDeviceIntPoint +APZCCallbackHelper::ApplyCallbackTransform(const LayoutDeviceIntPoint& aPoint, const ScrollableLayerGuid& aGuid, const CSSToLayoutDeviceScale& aScale, float aPresShellResolution) { LayoutDevicePoint point = LayoutDevicePoint(aPoint.x, aPoint.y); point = ApplyCallbackTransform(point / aScale, aGuid, aPresShellResolution) * aScale; - LayoutDeviceIntPoint ret = gfx::RoundedToInt(point); - return nsIntPoint(ret.x, ret.y); + return gfx::RoundedToInt(point); } nsEventStatus diff --git a/gfx/layers/apz/util/APZCCallbackHelper.h b/gfx/layers/apz/util/APZCCallbackHelper.h index 9f89c38fa297..a0c2b48ba771 100644 --- a/gfx/layers/apz/util/APZCCallbackHelper.h +++ b/gfx/layers/apz/util/APZCCallbackHelper.h @@ -99,13 +99,14 @@ public: const ScrollableLayerGuid& aGuid, float aPresShellResolution); - /* Same as above, but operates on nsIntPoint that are assumed to be in LayoutDevice - pixel space. Requires an additonal |aScale| parameter to convert between CSS and + /* Same as above, but operates on LayoutDeviceIntPoint. + Requires an additonal |aScale| parameter to convert between CSS and LayoutDevice space. */ - static nsIntPoint ApplyCallbackTransform(const nsIntPoint& aPoint, - const ScrollableLayerGuid& aGuid, - const CSSToLayoutDeviceScale& aScale, - float aPresShellResolution); + static mozilla::LayoutDeviceIntPoint + ApplyCallbackTransform(const LayoutDeviceIntPoint& aPoint, + const ScrollableLayerGuid& aGuid, + const CSSToLayoutDeviceScale& aScale, + float aPresShellResolution); /* Dispatch a widget event via the widget stored in the event, if any. * In a child process, allows the TabParent event-capture mechanism to diff --git a/layout/base/SelectionCarets.cpp b/layout/base/SelectionCarets.cpp index d0ed3bd476ab..df3a194e2f46 100644 --- a/layout/base/SelectionCarets.cpp +++ b/layout/base/SelectionCarets.cpp @@ -161,7 +161,7 @@ SelectionCarets::HandleEvent(WidgetEvent* aEvent) } WidgetTouchEvent *touchEvent = aEvent->AsTouchEvent(); - nsIntPoint movePoint; + LayoutDeviceIntPoint movePoint; int32_t nowTouchId = -1; if (touchEvent && !touchEvent->touches.IsEmpty()) { // If touch happened, just grab event with same identifier @@ -183,7 +183,7 @@ SelectionCarets::HandleEvent(WidgetEvent* aEvent) nowTouchId = touchEvent->touches[0]->Identifier(); } } else if (mouseEvent) { - movePoint = LayoutDeviceIntPoint::ToUntyped(mouseEvent->AsGUIEvent()->refPoint); + movePoint = mouseEvent->AsGUIEvent()->refPoint; } // Get event coordinate relative to root frame diff --git a/layout/base/TouchCaret.cpp b/layout/base/TouchCaret.cpp index 2feabc701f2a..d29eb02a88c3 100644 --- a/layout/base/TouchCaret.cpp +++ b/layout/base/TouchCaret.cpp @@ -629,7 +629,7 @@ TouchCaret::GetEventPosition(WidgetTouchEvent* aEvent, int32_t aIdentifier) if (aEvent->touches[i]->mIdentifier == aIdentifier) { // Get event coordinate relative to canvas frame. nsIFrame* canvasFrame = GetCanvasFrame(); - nsIntPoint touchIntPoint = aEvent->touches[i]->mRefPoint; + LayoutDeviceIntPoint touchIntPoint = aEvent->touches[i]->mRefPoint; return nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, touchIntPoint, canvasFrame); @@ -643,8 +643,7 @@ TouchCaret::GetEventPosition(WidgetMouseEvent* aEvent) { // Get event coordinate relative to canvas frame. nsIFrame* canvasFrame = GetCanvasFrame(); - nsIntPoint mouseIntPoint = - LayoutDeviceIntPoint::ToUntyped(aEvent->AsGUIEvent()->refPoint); + LayoutDeviceIntPoint mouseIntPoint = aEvent->AsGUIEvent()->refPoint; return nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, mouseIntPoint, canvasFrame); diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index c6679f802454..47812759ce52 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1912,13 +1912,13 @@ nsLayoutUtils::GetEventCoordinatesRelativeTo(const WidgetEvent* aEvent, return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); return GetEventCoordinatesRelativeTo(aEvent, - LayoutDeviceIntPoint::ToUntyped(aEvent->AsGUIEvent()->refPoint), + aEvent->AsGUIEvent()->refPoint, aFrame); } nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(const WidgetEvent* aEvent, - const nsIntPoint aPoint, + const LayoutDeviceIntPoint& aPoint, nsIFrame* aFrame) { if (!aFrame) { @@ -1935,7 +1935,7 @@ nsLayoutUtils::GetEventCoordinatesRelativeTo(const WidgetEvent* aEvent, nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(nsIWidget* aWidget, - const nsIntPoint aPoint, + const LayoutDeviceIntPoint& aPoint, nsIFrame* aFrame) { if (!aFrame || !aWidget) { @@ -2658,7 +2658,7 @@ static nsIntPoint WidgetToWidgetOffset(nsIWidget* aFrom, nsIWidget* aTo) { nsPoint nsLayoutUtils::TranslateWidgetToView(nsPresContext* aPresContext, - nsIWidget* aWidget, nsIntPoint aPt, + nsIWidget* aWidget, const LayoutDeviceIntPoint& aPt, nsView* aView) { nsPoint viewOffset; @@ -2667,7 +2667,8 @@ nsLayoutUtils::TranslateWidgetToView(nsPresContext* aPresContext, return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); } - nsIntPoint widgetPoint = aPt + WidgetToWidgetOffset(aWidget, viewWidget); + LayoutDeviceIntPoint widgetPoint = aPt + + LayoutDeviceIntPoint::FromUntyped(WidgetToWidgetOffset(aWidget, viewWidget)); nsPoint widgetAppUnits(aPresContext->DevPixelsToAppUnits(widgetPoint.x), aPresContext->DevPixelsToAppUnits(widgetPoint.y)); return widgetAppUnits - viewOffset; diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 319137e942f0..d2a034725117 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -679,7 +679,7 @@ public: */ static nsPoint GetEventCoordinatesRelativeTo( const mozilla::WidgetEvent* aEvent, - const nsIntPoint aPoint, + const mozilla::LayoutDeviceIntPoint& aPoint, nsIFrame* aFrame); /** @@ -693,7 +693,7 @@ public: * the event is not a GUI event). */ static nsPoint GetEventCoordinatesRelativeTo(nsIWidget* aWidget, - const nsIntPoint aPoint, + const mozilla::LayoutDeviceIntPoint& aPoint, nsIFrame* aFrame); /** @@ -716,7 +716,8 @@ public: * @return the point in the view's coordinates */ static nsPoint TranslateWidgetToView(nsPresContext* aPresContext, - nsIWidget* aWidget, nsIntPoint aPt, + nsIWidget* aWidget, + const mozilla::LayoutDeviceIntPoint& aPt, nsView* aView); /** diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 6b53f9e869f5..78d299df0694 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6753,8 +6753,7 @@ PresShell::RecordMouseLocation(WidgetGUIEvent* aEvent) if (!rootFrame) { nsView* rootView = mViewManager->GetRootView(); mMouseLocation = nsLayoutUtils::TranslateWidgetToView(mPresContext, - aEvent->widget, LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint), - rootView); + aEvent->widget, aEvent->refPoint, rootView); } else { mMouseLocation = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, rootFrame); @@ -8518,12 +8517,12 @@ PresShell::AdjustContextMenuKeyEvent(WidgetMouseEvent* aEvent) } // see if we should use the caret position for the popup - nsIntPoint caretPoint; + LayoutDeviceIntPoint caretPoint; // Beware! This may flush notifications via synchronous // ScrollSelectionIntoView. if (PrepareToUseCaretPosition(aEvent->widget, caretPoint)) { // caret position is good - aEvent->refPoint = LayoutDeviceIntPoint::FromUntyped(caretPoint); + aEvent->refPoint = caretPoint; return true; } @@ -8564,7 +8563,8 @@ PresShell::AdjustContextMenuKeyEvent(WidgetMouseEvent* aEvent) // relative to. The returned point is in device pixels realtive to the // widget passed in. bool -PresShell::PrepareToUseCaretPosition(nsIWidget* aEventWidget, nsIntPoint& aTargetPt) +PresShell::PrepareToUseCaretPosition(nsIWidget* aEventWidget, + LayoutDeviceIntPoint& aTargetPt) { nsresult rv; diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index 61662546ee3c..914cdd4476b7 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -690,7 +690,8 @@ protected: bool AdjustContextMenuKeyEvent(mozilla::WidgetMouseEvent* aEvent); // - bool PrepareToUseCaretPosition(nsIWidget* aEventWidget, nsIntPoint& aTargetPt); + bool PrepareToUseCaretPosition(nsIWidget* aEventWidget, + mozilla::LayoutDeviceIntPoint& aTargetPt); // Get the selected item and coordinates in device pixels relative to root // document's root view for element, first ensuring the element is onscreen diff --git a/layout/forms/nsNumberControlFrame.cpp b/layout/forms/nsNumberControlFrame.cpp index a2e1d686bfcd..dcaf97cc7cb2 100644 --- a/layout/forms/nsNumberControlFrame.cpp +++ b/layout/forms/nsNumberControlFrame.cpp @@ -585,8 +585,7 @@ nsNumberControlFrame::GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const LayoutDeviceIntPoint absPoint = aEvent->refPoint; nsPoint point = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, - LayoutDeviceIntPoint::ToUntyped(absPoint), - mSpinBox->GetPrimaryFrame()); + absPoint, mSpinBox->GetPrimaryFrame()); if (point != nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)) { if (point.y < mSpinBox->GetPrimaryFrame()->GetSize().height / 2) { return eSpinButtonUp; diff --git a/layout/forms/nsRangeFrame.cpp b/layout/forms/nsRangeFrame.cpp index d92fba89ff93..d57e603628f7 100644 --- a/layout/forms/nsRangeFrame.cpp +++ b/layout/forms/nsRangeFrame.cpp @@ -492,14 +492,12 @@ nsRangeFrame::GetValueAtEventPoint(WidgetGUIEvent* aEvent) if (aEvent->mClass == eTouchEventClass) { MOZ_ASSERT(aEvent->AsTouchEvent()->touches.Length() == 1, "Unexpected number of touches"); - absPoint = LayoutDeviceIntPoint::FromUntyped( - aEvent->AsTouchEvent()->touches[0]->mRefPoint); + absPoint = aEvent->AsTouchEvent()->touches[0]->mRefPoint; } else { absPoint = aEvent->refPoint; } nsPoint point = - nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, - LayoutDeviceIntPoint::ToUntyped(absPoint), this); + nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, absPoint, this); if (point == nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)) { // We don't want to change the current value for this error state. diff --git a/layout/xul/nsBoxFrame.cpp b/layout/xul/nsBoxFrame.cpp index d489026ae3b3..57ed08a24618 100644 --- a/layout/xul/nsBoxFrame.cpp +++ b/layout/xul/nsBoxFrame.cpp @@ -2097,7 +2097,8 @@ bool nsBoxFrame::GetEventPoint(WidgetGUIEvent* aEvent, nsPoint &aPoint) { nsIntPoint refPoint; bool res = GetEventPoint(aEvent, refPoint); - aPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, refPoint, this); + aPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo( + aEvent, LayoutDeviceIntPoint::FromUntyped(refPoint), this); return res; } @@ -2117,7 +2118,7 @@ nsBoxFrame::GetEventPoint(WidgetGUIEvent* aEvent, nsIntPoint &aPoint) { if (!touch) { return false; } - aPoint = touch->mRefPoint; + aPoint = LayoutDeviceIntPoint::ToUntyped(touch->mRefPoint); } else { aPoint = LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint); } diff --git a/widget/ContentHelper.cpp b/widget/ContentHelper.cpp index 53905106c549..894abaaf6688 100644 --- a/widget/ContentHelper.cpp +++ b/widget/ContentHelper.cpp @@ -75,7 +75,9 @@ ContentHelper::GetAllowedTouchBehavior(nsIWidget* aWidget, const nsIntPoint& aPo nsView *view = nsView::GetViewFor(aWidget); nsIFrame *viewFrame = view->GetFrame(); - nsPoint relativePoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aWidget, aPoint, viewFrame); + nsPoint relativePoint = + nsLayoutUtils::GetEventCoordinatesRelativeTo( + aWidget, LayoutDeviceIntPoint::FromUntyped(aPoint), viewFrame); nsIFrame *target = nsLayoutUtils::GetFrameForPoint(viewFrame, relativePoint, nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME); nsIScrollableFrame *nearestScrollableParent = nsLayoutUtils::GetNearestScrollableFrame(target, 0); diff --git a/widget/InputData.cpp b/widget/InputData.cpp index a0e85b4eef6e..4fd584258bae 100644 --- a/widget/InputData.cpp +++ b/widget/InputData.cpp @@ -21,7 +21,7 @@ already_AddRefed SingleTouchData::ToNewDOMTouch() const NS_ABORT_IF_FALSE(NS_IsMainThread(), "Can only create dom::Touch instances on main thread"); nsRefPtr touch = new Touch(mIdentifier, - nsIntPoint(mScreenPoint.x, mScreenPoint.y), + LayoutDeviceIntPoint(mScreenPoint.x, mScreenPoint.y), nsIntPoint(mRadius.width, mRadius.height), mRotationAngle, mForce); diff --git a/widget/android/AndroidJavaWrappers.cpp b/widget/android/AndroidJavaWrappers.cpp index 37a7804e3bf5..a3aefec79b24 100644 --- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -738,7 +738,7 @@ AndroidGeckoEvent::MakeTouchEvent(nsIWidget* widget) // and the Points() array has points in CSS pixels, which we need // to convert. CSSToLayoutDeviceScale scale = widget->GetDefaultScale(); - nsIntPoint pt( + LayoutDeviceIntPoint pt( (Points()[i].x * scale.scale) - offset.x, (Points()[i].y * scale.scale) - offset.y); nsIntPoint radii( diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 7d17657f4085..6d7bf270c97d 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -1095,7 +1095,7 @@ bool nsWindow::OnMultitouchEvent(AndroidGeckoEvent *ae) // retargeted. The Fennec browser.js code can use this to activate the // highlight element in case the this touchstart is the start of a tap. WidgetMouseEvent hittest(true, NS_MOUSE_MOZHITTEST, this, WidgetMouseEvent::eReal); - hittest.refPoint = LayoutDeviceIntPoint::FromUntyped(event.touches[0]->mRefPoint); + hittest.refPoint = event.touches[0]->mRefPoint; hittest.ignoreRootScrollFrame = true; hittest.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; nsEventStatus status; @@ -1140,8 +1140,8 @@ bool nsWindow::OnMultitouchEvent(AndroidGeckoEvent *ae) void nsWindow::OnNativeGestureEvent(AndroidGeckoEvent *ae) { - nsIntPoint pt(ae->Points()[0].x, - ae->Points()[0].y); + LayoutDeviceIntPoint pt(ae->Points()[0].x, + ae->Points()[0].y); double delta = ae->X(); int msg = 0; @@ -1170,7 +1170,7 @@ nsWindow::OnNativeGestureEvent(AndroidGeckoEvent *ae) void nsWindow::DispatchGestureEvent(uint32_t msg, uint32_t direction, double delta, - const nsIntPoint &refPoint, uint64_t time) + const LayoutDeviceIntPoint &refPoint, uint64_t time) { WidgetSimpleGestureEvent event(true, msg, this); @@ -1178,7 +1178,7 @@ nsWindow::DispatchGestureEvent(uint32_t msg, uint32_t direction, double delta, event.delta = delta; event.modifiers = 0; event.time = time; - event.refPoint = LayoutDeviceIntPoint::FromUntyped(refPoint); + event.refPoint = refPoint; DispatchEvent(&event); } diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h index 97dd2b7d7377..0c8f5d133804 100644 --- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -239,7 +239,7 @@ private: mozilla::AndroidGeckoEvent& key, ANPEvent* pluginEvent); void DispatchGestureEvent(uint32_t msg, uint32_t direction, double delta, - const nsIntPoint &refPoint, uint64_t time); + const mozilla::LayoutDeviceIntPoint &refPoint, uint64_t time); void HandleSpecialKey(mozilla::AndroidGeckoEvent *ae); void CreateLayerManager(int aCompositorWidth, int aCompositorHeight); void RedrawAll(); diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index bd17ccaf0491..8427526a0b85 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -286,8 +286,7 @@ struct ParamTraits } aResult->touches.AppendElement( new mozilla::dom::Touch( - identifier, mozilla::LayoutDeviceIntPoint::ToUntyped(refPoint), - radius, rotationAngle, force)); + identifier, refPoint, radius, rotationAngle, force)); } return true; } diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index da482eeb9f6c..5bd07ff155e4 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -6204,7 +6204,7 @@ bool nsWindow::OnTouch(WPARAM wParam, LPARAM lParam) touchPoint.ScreenToClient(mWnd); nsRefPtr touch = new Touch(pInputs[i].dwID, - touchPoint, + LayoutDeviceIntPoint::FromUntyped(touchPoint), /* radius, if known */ pInputs[i].dwFlags & TOUCHINPUTMASKF_CONTACTAREA ? nsIntPoint( From e6153bf650bccb92ef4dc1cad8b80170eaed6b6b Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Sun, 1 Feb 2015 17:27:41 -0500 Subject: [PATCH 05/16] Bug 1125040: Use LayoutDeviceIntPoint for GetEventPoint r=botond --- layout/xul/nsBoxFrame.cpp | 10 +++++----- layout/xul/nsBoxFrame.h | 3 ++- layout/xul/nsMenuPopupFrame.cpp | 4 +++- layout/xul/nsMenuPopupFrame.h | 4 +++- layout/xul/nsResizerFrame.cpp | 12 +++++++----- layout/xul/nsResizerFrame.h | 4 ++-- 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/layout/xul/nsBoxFrame.cpp b/layout/xul/nsBoxFrame.cpp index 57ed08a24618..69e4209154d7 100644 --- a/layout/xul/nsBoxFrame.cpp +++ b/layout/xul/nsBoxFrame.cpp @@ -2095,15 +2095,15 @@ nsBoxFrame::WrapListsInRedirector(nsDisplayListBuilder* aBuilder, bool nsBoxFrame::GetEventPoint(WidgetGUIEvent* aEvent, nsPoint &aPoint) { - nsIntPoint refPoint; + LayoutDeviceIntPoint refPoint; bool res = GetEventPoint(aEvent, refPoint); aPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo( - aEvent, LayoutDeviceIntPoint::FromUntyped(refPoint), this); + aEvent, refPoint, this); return res; } bool -nsBoxFrame::GetEventPoint(WidgetGUIEvent* aEvent, nsIntPoint &aPoint) { +nsBoxFrame::GetEventPoint(WidgetGUIEvent* aEvent, LayoutDeviceIntPoint& aPoint) { NS_ENSURE_TRUE(aEvent, false); WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent(); @@ -2118,9 +2118,9 @@ nsBoxFrame::GetEventPoint(WidgetGUIEvent* aEvent, nsIntPoint &aPoint) { if (!touch) { return false; } - aPoint = LayoutDeviceIntPoint::ToUntyped(touch->mRefPoint); + aPoint = touch->mRefPoint; } else { - aPoint = LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint); + aPoint = aEvent->refPoint; } return true; } diff --git a/layout/xul/nsBoxFrame.h b/layout/xul/nsBoxFrame.h index 32410a3fcd53..7b38fff84438 100644 --- a/layout/xul/nsBoxFrame.h +++ b/layout/xul/nsBoxFrame.h @@ -209,7 +209,8 @@ protected: bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent, nsPoint& aPoint); // Gets the event coordinates relative to the widget offset associated with // this frame. Return true if a single valid point was found. - bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent, nsIntPoint& aPoint); + bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent, + mozilla::LayoutDeviceIntPoint& aPoint); protected: void RegUnregAccessKey(bool aDoReg); diff --git a/layout/xul/nsMenuPopupFrame.cpp b/layout/xul/nsMenuPopupFrame.cpp index edc2e69d737a..b832579a3581 100644 --- a/layout/xul/nsMenuPopupFrame.cpp +++ b/layout/xul/nsMenuPopupFrame.cpp @@ -1477,7 +1477,9 @@ nsMenuPopupFrame::GetConstraintRect(const nsRect& aAnchorRect, return screenRect; } -void nsMenuPopupFrame::CanAdjustEdges(int8_t aHorizontalSide, int8_t aVerticalSide, nsIntPoint& aChange) +void nsMenuPopupFrame::CanAdjustEdges(int8_t aHorizontalSide, + int8_t aVerticalSide, + LayoutDeviceIntPoint& aChange) { int8_t popupAlign(mPopupAlignment); if (IsDirectionRTL()) { diff --git a/layout/xul/nsMenuPopupFrame.h b/layout/xul/nsMenuPopupFrame.h index adda6714d195..6012c698bf78 100644 --- a/layout/xul/nsMenuPopupFrame.h +++ b/layout/xul/nsMenuPopupFrame.h @@ -366,7 +366,9 @@ public: // Later, when bug 357725 is implemented, we can make this adjust aChange by // the amount that the side can be resized, so that minimums and maximums // can be taken into account. - void CanAdjustEdges(int8_t aHorizontalSide, int8_t aVerticalSide, nsIntPoint& aChange); + void CanAdjustEdges(int8_t aHorizontalSide, + int8_t aVerticalSide, + mozilla::LayoutDeviceIntPoint& aChange); // Return true if the popup is positioned relative to an anchor. bool IsAnchored() const { return mScreenXPos == -1 && mScreenYPos == -1; } diff --git a/layout/xul/nsResizerFrame.cpp b/layout/xul/nsResizerFrame.cpp index 950de191e4c2..228fbd77ae09 100644 --- a/layout/xul/nsResizerFrame.cpp +++ b/layout/xul/nsResizerFrame.cpp @@ -114,10 +114,11 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, } // remember current mouse coordinates - nsIntPoint refPoint; + LayoutDeviceIntPoint refPoint; if (!GetEventPoint(aEvent, refPoint)) return NS_OK; - mMouseDownPoint = refPoint + aEvent->widget->WidgetToScreenOffset(); + mMouseDownPoint = refPoint + + LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); // we're tracking mTrackingMouseMove = true; @@ -162,11 +163,12 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, // retrieve the offset of the mousemove event relative to the mousedown. // The difference is how much the resize needs to be - nsIntPoint refPoint; + LayoutDeviceIntPoint refPoint; if (!GetEventPoint(aEvent, refPoint)) return NS_OK; - nsIntPoint screenPoint(refPoint + aEvent->widget->WidgetToScreenOffset()); - nsIntPoint mouseMove(screenPoint - mMouseDownPoint); + LayoutDeviceIntPoint screenPoint = refPoint + + LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint mouseMove(screenPoint - mMouseDownPoint); // Determine which direction to resize by checking the dir attribute. // For windows and menus, ensure that it can be resized in that direction. diff --git a/layout/xul/nsResizerFrame.h b/layout/xul/nsResizerFrame.h index faa75e994340..50dab5141627 100644 --- a/layout/xul/nsResizerFrame.h +++ b/layout/xul/nsResizerFrame.h @@ -66,8 +66,8 @@ protected: static void RestoreOriginalSize(nsIContent* aContent); protected: - nsIntRect mMouseDownRect; - nsIntPoint mMouseDownPoint; + nsIntRect mMouseDownRect; + LayoutDeviceIntPoint mMouseDownPoint; }; // class nsResizerFrame #endif /* nsResizerFrame_h___ */ From 7d34edce07694612f11fca95fac5748e9b694ddb Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Sun, 1 Feb 2015 17:27:41 -0500 Subject: [PATCH 06/16] Bug 1125040: Use LayoutDeviceIntPoint for nsIWidget::WidgetToScreen r=botond --- accessible/generic/HyperTextAccessible.cpp | 2 +- dom/base/nsDOMWindowUtils.cpp | 3 +-- dom/base/nsQueryContentEventResult.cpp | 4 ++-- dom/events/ContentEventHandler.cpp | 8 +++----- dom/events/Event.cpp | 3 +-- dom/events/EventStateManager.cpp | 21 ++++++++----------- dom/events/IMEContentObserver.cpp | 9 ++++---- dom/events/UIEvent.h | 3 +-- dom/events/WheelHandlingHelper.cpp | 4 ++-- dom/plugins/base/nsPluginInstanceOwner.cpp | 3 +-- embedding/browser/nsDocShellTreeOwner.cpp | 2 +- gfx/tests/gtest/TestCompositor.cpp | 2 +- layout/base/PositionedEventTargeting.cpp | 4 ++-- layout/base/nsLayoutUtils.cpp | 24 +++++++++++----------- layout/base/nsLayoutUtils.h | 7 ++++--- layout/base/nsPresShell.cpp | 4 ++-- layout/generic/nsFrame.cpp | 2 +- layout/xul/nsResizerFrame.cpp | 6 ++---- layout/xul/nsXULPopupManager.cpp | 2 +- view/nsView.cpp | 2 +- widget/PuppetWidget.h | 4 ++-- widget/android/AndroidJavaWrappers.cpp | 7 +++---- widget/android/nsWindow.cpp | 9 ++++---- widget/android/nsWindow.h | 2 +- widget/cocoa/nsChildView.h | 2 +- widget/cocoa/nsChildView.mm | 10 ++++----- widget/cocoa/nsCocoaWindow.h | 2 +- widget/cocoa/nsCocoaWindow.mm | 6 +++--- widget/gonk/nsWindow.cpp | 4 ++-- widget/gonk/nsWindow.h | 2 +- widget/gtk/nsDragService.cpp | 2 +- widget/gtk/nsWindow.cpp | 23 +++++++++------------ widget/gtk/nsWindow.h | 2 +- widget/nsIWidget.h | 8 ++++++-- widget/qt/nsWindow.cpp | 4 ++-- widget/qt/nsWindow.h | 2 +- widget/windows/nsIMM32Handler.cpp | 8 ++++---- widget/windows/nsTextStore.cpp | 8 ++++---- widget/windows/nsWindow.cpp | 8 ++++---- widget/windows/nsWindow.h | 2 +- widget/windows/winrt/MetroWidget.cpp | 4 ++-- widget/windows/winrt/MetroWidget.h | 2 +- 42 files changed, 112 insertions(+), 124 deletions(-) diff --git a/accessible/generic/HyperTextAccessible.cpp b/accessible/generic/HyperTextAccessible.cpp index 3d394e24a0fc..5681aa01331e 100644 --- a/accessible/generic/HyperTextAccessible.cpp +++ b/accessible/generic/HyperTextAccessible.cpp @@ -1344,7 +1344,7 @@ HyperTextAccessible::GetCaretRect(nsIWidget** aWidget) nsIntRect caretRect; caretRect = rect.ToOutsidePixels(frame->PresContext()->AppUnitsPerDevPixel()); // ((content screen origin) - (content offset in the widget)) = widget origin on the screen - caretRect.MoveBy((*aWidget)->WidgetToScreenOffset() - (*aWidget)->GetClientOffset()); + caretRect.MoveBy((*aWidget)->WidgetToScreenOffsetUntyped() - (*aWidget)->GetClientOffset()); // Correct for character size, so that caret always matches the size of // the character. This is important for font size transitions, and is diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 638b13eabf63..6787241774cc 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2195,8 +2195,7 @@ nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType, } } - pt += LayoutDeviceIntPoint::FromUntyped( - widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset()); + pt += widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset(); WidgetQueryContentEvent queryEvent(true, aType, targetWidget); InitEvent(queryEvent, &pt); diff --git a/dom/base/nsQueryContentEventResult.cpp b/dom/base/nsQueryContentEventResult.cpp index bd2b7aee63b4..c451952a03f9 100644 --- a/dom/base/nsQueryContentEventResult.cpp +++ b/dom/base/nsQueryContentEventResult.cpp @@ -147,7 +147,7 @@ nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget, } // Convert the top widget related coordinates to the given widget's. - nsIntPoint offset = + LayoutDeviceIntPoint offset = aWidget->WidgetToScreenOffset() - topWidget->WidgetToScreenOffset(); - mRect.MoveBy(-offset); + mRect.MoveBy(-LayoutDeviceIntPoint::ToUntyped(offset)); } diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp index f5e83a2e89b2..3c3665a50a93 100644 --- a/dom/events/ContentEventHandler.cpp +++ b/dom/events/ContentEventHandler.cpp @@ -1149,9 +1149,8 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent) eventOnRoot.mUseNativeLineBreak = aEvent->mUseNativeLineBreak; eventOnRoot.refPoint = aEvent->refPoint; if (rootWidget != aEvent->widget) { - eventOnRoot.refPoint += LayoutDeviceIntPoint::FromUntyped( - aEvent->widget->WidgetToScreenOffset() - - rootWidget->WidgetToScreenOffset()); + eventOnRoot.refPoint += aEvent->widget->WidgetToScreenOffset() - + rootWidget->WidgetToScreenOffset(); } nsPoint ptInRoot = nsLayoutUtils::GetEventCoordinatesRelativeTo(&eventOnRoot, rootFrame); @@ -1214,8 +1213,7 @@ ContentEventHandler::OnQueryDOMWidgetHittest(WidgetQueryContentEvent* aEvent) nsIFrame* docFrame = mPresShell->GetRootFrame(); NS_ENSURE_TRUE(docFrame, NS_ERROR_FAILURE); - LayoutDeviceIntPoint eventLoc = aEvent->refPoint + - LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint eventLoc = aEvent->refPoint + aEvent->widget->WidgetToScreenOffset(); nsIntRect docFrameRect = docFrame->GetScreenRect(); // Returns CSS pixels CSSIntPoint eventLocCSS( mPresContext->DevPixelsToIntCSSPixels(eventLoc.x) - docFrameRect.x, diff --git a/dom/events/Event.cpp b/dom/events/Event.cpp index e7d967814d34..04dbbf56b062 100644 --- a/dom/events/Event.cpp +++ b/dom/events/Event.cpp @@ -902,8 +902,7 @@ Event::GetScreenCoords(nsPresContext* aPresContext, return LayoutDeviceIntPoint::ToUntyped(aPoint); } - LayoutDeviceIntPoint offset = aPoint + - LayoutDeviceIntPoint::FromUntyped(guiEvent->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint offset = aPoint + guiEvent->widget->WidgetToScreenOffset(); nscoord factor = aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom(); return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor), diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index 371990d1b8b1..81dd8ad630f8 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -1505,8 +1505,7 @@ EventStateManager::BeginTrackingDragGesture(nsPresContext* aPresContext, // Note that |inDownEvent| could be either a mouse down event or a // synthesized mouse move event. - mGestureDownPoint = inDownEvent->refPoint + - LayoutDeviceIntPoint::FromUntyped(inDownEvent->widget->WidgetToScreenOffset()); + mGestureDownPoint = inDownEvent->refPoint + inDownEvent->widget->WidgetToScreenOffset(); inDownFrame->GetContentForEvent(inDownEvent, getter_AddRefs(mGestureDownContent)); @@ -1544,8 +1543,7 @@ EventStateManager::FillInEventFromGestureDown(WidgetMouseEvent* aEvent) // Set the coordinates in the new event to the coordinates of // the old event, adjusted for the fact that the widget might be // different - aEvent->refPoint = mGestureDownPoint - - LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); + aEvent->refPoint = mGestureDownPoint - aEvent->widget->WidgetToScreenOffset(); aEvent->modifiers = mGestureModifiers; aEvent->buttons = mGestureDownButtons; } @@ -1601,8 +1599,7 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext, } // fire drag gesture if mouse has moved enough - LayoutDeviceIntPoint pt = aEvent->refPoint + - LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint pt = aEvent->refPoint + aEvent->widget->WidgetToScreenOffset(); LayoutDeviceIntPoint distance = pt - mGestureDownPoint; if (Abs(distance.x) > AssertedCast(pixelThresholdX) || Abs(distance.y) > AssertedCast(pixelThresholdY)) { @@ -3216,9 +3213,9 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext, WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent(); event.refPoint = mouseEvent->refPoint; if (mouseEvent->widget) { - event.refPoint += LayoutDeviceIntPoint::FromUntyped(mouseEvent->widget->WidgetToScreenOffset()); + event.refPoint += mouseEvent->widget->WidgetToScreenOffset(); } - event.refPoint -= LayoutDeviceIntPoint::FromUntyped(widget->WidgetToScreenOffset()); + event.refPoint -= widget->WidgetToScreenOffset(); event.modifiers = mouseEvent->modifiers; event.buttons = mouseEvent->buttons; event.inputSource = mouseEvent->inputSource; @@ -4023,8 +4020,8 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent) // in the other branch here. sSynthCenteringPoint = center; aMouseEvent->widget->SynthesizeNativeMouseMove( - LayoutDeviceIntPoint::ToUntyped(center) + - aMouseEvent->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint::ToUntyped(center + + aMouseEvent->widget->WidgetToScreenOffset())); } else if (aMouseEvent->refPoint == sSynthCenteringPoint) { // This is the "synthetic native" event we dispatched to re-center the // pointer. Cancel it so we don't expose the centering move to content. @@ -4160,7 +4157,7 @@ EventStateManager::SetPointerLock(nsIWidget* aWidget, aWidget, mPresContext); aWidget->SynthesizeNativeMouseMove( - LayoutDeviceIntPoint::ToUntyped(sLastRefPoint) + aWidget->WidgetToScreenOffset()); + LayoutDeviceIntPoint::ToUntyped(sLastRefPoint + aWidget->WidgetToScreenOffset())); // Retarget all events to this element via capture. nsIPresShell::SetCapturingContent(aElement, CAPTURE_POINTERLOCK); @@ -4176,7 +4173,7 @@ EventStateManager::SetPointerLock(nsIWidget* aWidget, // no movement. sLastRefPoint = mPreLockPoint; aWidget->SynthesizeNativeMouseMove( - LayoutDeviceIntPoint::ToUntyped(mPreLockPoint) + aWidget->WidgetToScreenOffset()); + LayoutDeviceIntPoint::ToUntyped(mPreLockPoint + aWidget->WidgetToScreenOffset())); // Don't retarget events to this element any more. nsIPresShell::SetCapturingContent(nullptr, CAPTURE_POINTERLOCK); diff --git a/dom/events/IMEContentObserver.cpp b/dom/events/IMEContentObserver.cpp index 836c6882abce..ac9de57b071e 100644 --- a/dom/events/IMEContentObserver.cpp +++ b/dom/events/IMEContentObserver.cpp @@ -449,15 +449,14 @@ IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext, nsIWidget* topLevelWidget = mWidget->GetTopLevelWidget(); if (topLevelWidget && topLevelWidget != mWidget) { charAtPt.mReply.mRect.MoveBy( - topLevelWidget->WidgetToScreenOffset() - - mWidget->WidgetToScreenOffset()); + topLevelWidget->WidgetToScreenOffsetUntyped() - + mWidget->WidgetToScreenOffsetUntyped()); } // The refPt is relative to its widget. // We should notify it with offset in the widget. if (aMouseEvent->widget != mWidget) { - charAtPt.refPoint += LayoutDeviceIntPoint::FromUntyped( - aMouseEvent->widget->WidgetToScreenOffset() - - mWidget->WidgetToScreenOffset()); + charAtPt.refPoint += aMouseEvent->widget->WidgetToScreenOffset() - + mWidget->WidgetToScreenOffset(); } IMENotification notification(NOTIFY_IME_OF_MOUSE_BUTTON_EVENT); diff --git a/dom/events/UIEvent.h b/dom/events/UIEvent.h index d13dc7880199..81b6097286b8 100644 --- a/dom/events/UIEvent.h +++ b/dom/events/UIEvent.h @@ -57,8 +57,7 @@ public: return LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint); } - LayoutDeviceIntPoint offset = aEvent->refPoint + - LayoutDeviceIntPoint::FromUntyped(event->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint offset = aEvent->refPoint + event->widget->WidgetToScreenOffset(); nscoord factor = aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom(); return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor), diff --git a/dom/events/WheelHandlingHelper.cpp b/dom/events/WheelHandlingHelper.cpp index ba586cfc3684..35441dd930a9 100644 --- a/dom/events/WheelHandlingHelper.cpp +++ b/dom/events/WheelHandlingHelper.cpp @@ -293,8 +293,8 @@ WheelTransaction::GetScreenPoint(WidgetGUIEvent* aEvent) { NS_ASSERTION(aEvent, "aEvent is null"); NS_ASSERTION(aEvent->widget, "aEvent-widget is null"); - return LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint) + - aEvent->widget->WidgetToScreenOffset(); + return LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint + + aEvent->widget->WidgetToScreenOffset()); } /* static */ uint32_t diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 13f8d8484bfb..e3c6e1ef5787 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -2121,8 +2121,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent) // Get reference point relative to screen: LayoutDeviceIntPoint rootPoint(-1, -1); if (widget) - rootPoint = anEvent.refPoint + - LayoutDeviceIntPoint::FromUntyped(widget->WidgetToScreenOffset()); + rootPoint = anEvent.refPoint + widget->WidgetToScreenOffset(); #ifdef MOZ_WIDGET_GTK Window root = GDK_ROOT_WINDOW(); #elif defined(MOZ_WIDGET_QT) diff --git a/embedding/browser/nsDocShellTreeOwner.cpp b/embedding/browser/nsDocShellTreeOwner.cpp index e4490a61e9ee..4787a2c2408a 100644 --- a/embedding/browser/nsDocShellTreeOwner.cpp +++ b/embedding/browser/nsDocShellTreeOwner.cpp @@ -1452,7 +1452,7 @@ ChromeTooltipListener::sTooltipCallback(nsITimer *aTimer, if (textFound) { nsString tipText(tooltipText); - nsIntPoint screenDot = widget->WidgetToScreenOffset(); + LayoutDeviceIntPoint screenDot = widget->WidgetToScreenOffset(); self->ShowTooltip(self->mMouseScreenX - screenDot.x, self->mMouseScreenY - screenDot.y, tipText); diff --git a/gfx/tests/gtest/TestCompositor.cpp b/gfx/tests/gtest/TestCompositor.cpp index cf0b9bf3664f..a8cf3c2674b9 100644 --- a/gfx/tests/gtest/TestCompositor.cpp +++ b/gfx/tests/gtest/TestCompositor.cpp @@ -71,7 +71,7 @@ public: virtual nsresult ConfigureChildren(const nsTArray& aConfigurations) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD Invalidate(const nsIntRect &aRect) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD SetTitle(const nsAString& title) MOZ_OVERRIDE { return NS_OK; } - virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE { return nsIntPoint(0, 0); } + virtual LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE { return LayoutDeviceIntPoint(0, 0); } NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, bool aDoCapture) MOZ_OVERRIDE { return NS_OK; } diff --git a/layout/base/PositionedEventTargeting.cpp b/layout/base/PositionedEventTargeting.cpp index 99c26818c864..21c87473ab74 100644 --- a/layout/base/PositionedEventTargeting.cpp +++ b/layout/base/PositionedEventTargeting.cpp @@ -473,11 +473,11 @@ FindFrameTargetedByInputEvent(WidgetGUIEvent* aEvent, if (!view) { return target; } - nsIntPoint widgetPoint = nsLayoutUtils::TranslateViewToWidget( + LayoutDeviceIntPoint widgetPoint = nsLayoutUtils::TranslateViewToWidget( aRootFrame->PresContext(), view, point, aEvent->widget); if (widgetPoint.x != NS_UNCONSTRAINEDSIZE) { // If that succeeded, we update the point in the event - aEvent->refPoint = LayoutDeviceIntPoint::FromUntyped(widgetPoint); + aEvent->refPoint = widgetPoint; } return target; } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 47812759ce52..8fe15aef9ff9 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -2627,8 +2627,8 @@ nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame, NSFloatPixelsToAppUnits(float(result.height), destAppUnitsPerDevPixel)); } -static nsIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) { - nsIntPoint offset(0, 0); +static LayoutDeviceIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) { + LayoutDeviceIntPoint offset(0, 0); while ((aWidget->WindowType() == eWindowType_child || aWidget->IsPlugin())) { nsIWidget* parent = aWidget->GetParent(); @@ -2637,18 +2637,19 @@ static nsIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) { } nsIntRect bounds; aWidget->GetBounds(bounds); - offset += bounds.TopLeft(); + offset += LayoutDeviceIntPoint::FromUntyped(bounds.TopLeft()); aWidget = parent; } aRootWidget = aWidget; return offset; } -static nsIntPoint WidgetToWidgetOffset(nsIWidget* aFrom, nsIWidget* aTo) { +static LayoutDeviceIntPoint +WidgetToWidgetOffset(nsIWidget* aFrom, nsIWidget* aTo) { nsIWidget* fromRoot; - nsIntPoint fromOffset = GetWidgetOffset(aFrom, fromRoot); + LayoutDeviceIntPoint fromOffset = GetWidgetOffset(aFrom, fromRoot); nsIWidget* toRoot; - nsIntPoint toOffset = GetWidgetOffset(aTo, toRoot); + LayoutDeviceIntPoint toOffset = GetWidgetOffset(aTo, toRoot); if (fromRoot == toRoot) { return fromOffset - toOffset; @@ -2667,14 +2668,13 @@ nsLayoutUtils::TranslateWidgetToView(nsPresContext* aPresContext, return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); } - LayoutDeviceIntPoint widgetPoint = aPt + - LayoutDeviceIntPoint::FromUntyped(WidgetToWidgetOffset(aWidget, viewWidget)); + LayoutDeviceIntPoint widgetPoint = aPt + WidgetToWidgetOffset(aWidget, viewWidget); nsPoint widgetAppUnits(aPresContext->DevPixelsToAppUnits(widgetPoint.x), aPresContext->DevPixelsToAppUnits(widgetPoint.y)); return widgetAppUnits - viewOffset; } -nsIntPoint +LayoutDeviceIntPoint nsLayoutUtils::TranslateViewToWidget(nsPresContext* aPresContext, nsView* aView, nsPoint aPt, nsIWidget* aWidget) @@ -2682,11 +2682,11 @@ nsLayoutUtils::TranslateViewToWidget(nsPresContext* aPresContext, nsPoint viewOffset; nsIWidget* viewWidget = aView->GetNearestWidget(&viewOffset); if (!viewWidget) { - return nsIntPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); + return LayoutDeviceIntPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); } - nsIntPoint relativeToViewWidget(aPresContext->AppUnitsToDevPixels(aPt.x + viewOffset.x), - aPresContext->AppUnitsToDevPixels(aPt.y + viewOffset.y)); + LayoutDeviceIntPoint relativeToViewWidget(aPresContext->AppUnitsToDevPixels(aPt.x + viewOffset.x), + aPresContext->AppUnitsToDevPixels(aPt.y + viewOffset.y)); return relativeToViewWidget + WidgetToWidgetOffset(viewWidget, aWidget); } diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index d2a034725117..e733e72ebdff 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -728,9 +728,10 @@ public: * @param aWidget the widget to which returned coordinates are relative * @return the point in the view's coordinates */ - static nsIntPoint TranslateViewToWidget(nsPresContext* aPresContext, - nsView* aView, nsPoint aPt, - nsIWidget* aWidget); + static mozilla::LayoutDeviceIntPoint + TranslateViewToWidget(nsPresContext* aPresContext, + nsView* aView, nsPoint aPt, + nsIWidget* aWidget); enum FrameForPointFlags { /** diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 78d299df0694..4f1c7bd62a80 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -8474,9 +8474,9 @@ PresShell::AdjustContextMenuKeyEvent(WidgetMouseEvent* aEvent) nsCOMPtr widget = popupFrame->GetNearestWidget(); aEvent->widget = widget; - nsIntPoint widgetPoint = widget->WidgetToScreenOffset(); + LayoutDeviceIntPoint widgetPoint = widget->WidgetToScreenOffset(); aEvent->refPoint = LayoutDeviceIntPoint::FromUntyped( - itemFrame->GetScreenRect().BottomLeft() - widgetPoint); + itemFrame->GetScreenRect().BottomLeft()) - widgetPoint; mCurrentEventContent = itemFrame->GetContent(); mCurrentEventFrame = itemFrame; diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index a26dff22b199..cd4b0f7376b7 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4812,7 +4812,7 @@ nsRect nsIFrame::GetScreenRectInAppUnits() const nsCOMPtr rootWidget; presContext->PresShell()->GetViewManager()->GetRootWidget(getter_AddRefs(rootWidget)); if (rootWidget) { - nsIntPoint rootDevPx = rootWidget->WidgetToScreenOffset(); + LayoutDeviceIntPoint rootDevPx = rootWidget->WidgetToScreenOffset(); rootScreenPos.x = presContext->DevPixelsToAppUnits(rootDevPx.x); rootScreenPos.y = presContext->DevPixelsToAppUnits(rootDevPx.y); } diff --git a/layout/xul/nsResizerFrame.cpp b/layout/xul/nsResizerFrame.cpp index 228fbd77ae09..afdab2b22911 100644 --- a/layout/xul/nsResizerFrame.cpp +++ b/layout/xul/nsResizerFrame.cpp @@ -117,8 +117,7 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, LayoutDeviceIntPoint refPoint; if (!GetEventPoint(aEvent, refPoint)) return NS_OK; - mMouseDownPoint = refPoint + - LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); + mMouseDownPoint = refPoint + aEvent->widget->WidgetToScreenOffset(); // we're tracking mTrackingMouseMove = true; @@ -166,8 +165,7 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, LayoutDeviceIntPoint refPoint; if (!GetEventPoint(aEvent, refPoint)) return NS_OK; - LayoutDeviceIntPoint screenPoint = refPoint + - LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); + LayoutDeviceIntPoint screenPoint = refPoint + aEvent->widget->WidgetToScreenOffset(); LayoutDeviceIntPoint mouseMove(screenPoint - mMouseDownPoint); // Determine which direction to resize by checking the dir attribute. diff --git a/layout/xul/nsXULPopupManager.cpp b/layout/xul/nsXULPopupManager.cpp index 220749bedc28..eb5e7b1ae0cb 100644 --- a/layout/xul/nsXULPopupManager.cpp +++ b/layout/xul/nsXULPopupManager.cpp @@ -729,7 +729,7 @@ nsXULPopupManager::ShowTooltipAtScreen(nsIContent* aPopup, if (rootPresContext) { nsIWidget *rootWidget = rootPresContext->GetRootWidget(); if (rootWidget) { - mCachedMousePoint -= rootWidget->WidgetToScreenOffset(); + mCachedMousePoint -= rootWidget->WidgetToScreenOffsetUntyped(); } } diff --git a/view/nsView.cpp b/view/nsView.cpp index 7ca917cb8a6e..63b0e4ba46ec 100644 --- a/view/nsView.cpp +++ b/view/nsView.cpp @@ -220,7 +220,7 @@ nsIntRect nsView::CalcWidgetBounds(nsWindowType aType) if (parentWidget && aType == eWindowType_popup && IsEffectivelyVisible()) { // put offset into screen coordinates. (based on client area origin) - nsIntPoint screenPoint = parentWidget->WidgetToScreenOffset(); + LayoutDeviceIntPoint screenPoint = parentWidget->WidgetToScreenOffset(); viewBounds += nsPoint(NSIntPixelsToAppUnits(screenPoint.x, p2a), NSIntPixelsToAppUnits(screenPoint.y, p2a)); } diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index d9c5dd6d00bf..95f9b77083f5 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -126,8 +126,8 @@ public: { return NS_ERROR_UNEXPECTED; } // PuppetWidgets are always at <0, 0>. - virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE - { return nsIntPoint(0, 0); } + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE + { return mozilla::LayoutDeviceIntPoint(0, 0); } void InitEvent(WidgetGUIEvent& aEvent, nsIntPoint* aPoint = nullptr); diff --git a/widget/android/AndroidJavaWrappers.cpp b/widget/android/AndroidJavaWrappers.cpp index a3aefec79b24..27e9ffed4d75 100644 --- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -730,7 +730,7 @@ AndroidGeckoEvent::MakeTouchEvent(nsIWidget* widget) event.modifiers = DOMModifiers(); event.time = Time(); - const nsIntPoint& offset = widget->WidgetToScreenOffset(); + const LayoutDeviceIntPoint& offset = widget->WidgetToScreenOffset(); event.touches.SetCapacity(endIndex - startIndex); for (int i = startIndex; i < endIndex; i++) { // In this code branch, we are dispatching this event directly @@ -796,7 +796,7 @@ AndroidGeckoEvent::MakeMultiTouchInput(nsIWidget* widget) return event; } - const nsIntPoint& offset = widget->WidgetToScreenOffset(); + const nsIntPoint& offset = widget->WidgetToScreenOffsetUntyped(); event.mTouches.SetCapacity(endIndex - startIndex); for (int i = startIndex; i < endIndex; i++) { nsIntPoint point = Points()[i] - offset; @@ -853,11 +853,10 @@ AndroidGeckoEvent::MakeMouseEvent(nsIWidget* widget) // We are dispatching this event directly into Gecko (as opposed to going // through the AsyncPanZoomController), and the Points() array has points // in CSS pixels, which we need to convert to LayoutDevice pixels. - const nsIntPoint& offset = widget->WidgetToScreenOffset(); + const LayoutDeviceIntPoint& offset = widget->WidgetToScreenOffset(); CSSToLayoutDeviceScale scale = widget->GetDefaultScale(); event.refPoint = LayoutDeviceIntPoint((Points()[0].x * scale.scale) - offset.x, (Points()[0].y * scale.scale) - offset.y); - return event; } diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 6d7bf270c97d..84edc194d12a 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -630,7 +630,7 @@ nsWindow::BringToFront() NS_IMETHODIMP nsWindow::GetScreenBounds(nsIntRect &aRect) { - nsIntPoint p = WidgetToScreenOffset(); + LayoutDeviceIntPoint p = WidgetToScreenOffset(); aRect.x = p.x; aRect.y = p.y; @@ -640,10 +640,10 @@ nsWindow::GetScreenBounds(nsIntRect &aRect) return NS_OK; } -nsIntPoint +LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() { - nsIntPoint p(0, 0); + LayoutDeviceIntPoint p(0, 0); nsWindow *w = this; while (w && !w->IsTopLevel()) { @@ -1041,8 +1041,7 @@ nsWindow::OnContextmenuEvent(AndroidGeckoEvent *ae) WidgetMouseEvent contextMenuEvent(true, NS_CONTEXTMENU, this, WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); contextMenuEvent.refPoint = - LayoutDeviceIntPoint(RoundedToInt(pt * GetDefaultScale())) - - LayoutDeviceIntPoint::FromUntyped(WidgetToScreenOffset()); + RoundedToInt(pt * GetDefaultScale()) - WidgetToScreenOffset(); contextMenuEvent.ignoreRootScrollFrame = true; contextMenuEvent.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h index 0c8f5d133804..e21edf050c15 100644 --- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -100,7 +100,7 @@ public: NS_IMETHOD Invalidate(const nsIntRect &aRect); NS_IMETHOD SetFocus(bool aRaise = false); NS_IMETHOD GetScreenBounds(nsIntRect &aRect); - virtual nsIntPoint WidgetToScreenOffset(); + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus); nsEventStatus DispatchEvent(mozilla::WidgetGUIEvent* aEvent); diff --git a/widget/cocoa/nsChildView.h b/widget/cocoa/nsChildView.h index 65aaef78f2ff..a1be2604df40 100644 --- a/widget/cocoa/nsChildView.h +++ b/widget/cocoa/nsChildView.h @@ -401,7 +401,7 @@ public: virtual void* GetNativeData(uint32_t aDataType) MOZ_OVERRIDE; virtual nsresult ConfigureChildren(const nsTArray& aConfigurations) MOZ_OVERRIDE; - virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; virtual bool ShowsResizeIndicator(nsIntRect* aResizerRect) MOZ_OVERRIDE; static bool ConvertStatus(nsEventStatus aStatus) diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 2bbf250b33e8..369eadd17ed3 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -923,7 +923,7 @@ NS_IMETHODIMP nsChildView::GetClientBounds(nsIntRect &aRect) if (!mParentWidget) { // For top level widgets we want the position on screen, not the position // of this view inside the window. - aRect.MoveTo(WidgetToScreenOffset()); + aRect.MoveTo(WidgetToScreenOffsetUntyped()); } return NS_OK; } @@ -931,7 +931,7 @@ NS_IMETHODIMP nsChildView::GetClientBounds(nsIntRect &aRect) NS_IMETHODIMP nsChildView::GetScreenBounds(nsIntRect &aRect) { GetBounds(aRect); - aRect.MoveTo(WidgetToScreenOffset()); + aRect.MoveTo(WidgetToScreenOffsetUntyped()); return NS_OK; } @@ -1482,7 +1482,7 @@ void nsChildView::ReportSizeEvent() // Return the offset between this child view and the screen. // @return -- widget origin in device-pixel coords -nsIntPoint nsChildView::WidgetToScreenOffset() +LayoutDeviceIntPoint nsChildView::WidgetToScreenOffset() { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; @@ -1500,9 +1500,9 @@ nsIntPoint nsChildView::WidgetToScreenOffset() FlipCocoaScreenCoordinate(origin); // convert to device pixels - return CocoaPointsToDevPixels(origin); + return LayoutDeviceIntPoint::FromUntyped(CocoaPointsToDevPixels(origin)); - NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(nsIntPoint(0,0)); + NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(LayoutDeviceIntPoint(0,0)); } NS_IMETHODIMP nsChildView::CaptureRollupEvents(nsIRollupListener * aListener, diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h index 814cd73b0198..530f05c4a58d 100644 --- a/widget/cocoa/nsCocoaWindow.h +++ b/widget/cocoa/nsCocoaWindow.h @@ -260,7 +260,7 @@ public: NS_IMETHOD SetModal(bool aState) MOZ_OVERRIDE; virtual bool IsVisible() const MOZ_OVERRIDE; NS_IMETHOD SetFocus(bool aState=false) MOZ_OVERRIDE; - virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; virtual nsIntPoint GetClientOffset() MOZ_OVERRIDE; virtual nsIntSize ClientToWindowSize(const nsIntSize& aClientSize) MOZ_OVERRIDE; diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index d5936bec4786..f75d2195bc19 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -1812,7 +1812,7 @@ NS_IMETHODIMP nsCocoaWindow::SetFocus(bool aState) return NS_OK; } -nsIntPoint nsCocoaWindow::WidgetToScreenOffset() +LayoutDeviceIntPoint nsCocoaWindow::WidgetToScreenOffset() { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; @@ -1823,9 +1823,9 @@ nsIntPoint nsCocoaWindow::WidgetToScreenOffset() } r = nsCocoaUtils::CocoaRectToGeckoRectDevPix(rect, BackingScaleFactor()); - return r.TopLeft(); + return LayoutDeviceIntPoint::FromUntyped(r.TopLeft()); - NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(nsIntPoint(0,0)); + NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(LayoutDeviceIntPoint(0,0)); } nsIntPoint nsCocoaWindow::GetClientOffset() diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index 732d3a33e7a5..ea9131dccea6 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -522,10 +522,10 @@ nsWindow::Invalidate(const nsIntRect &aRect) return NS_OK; } -nsIntPoint +LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() { - nsIntPoint p(0, 0); + LayoutDeviceIntPoint p(0, 0); nsWindow *w = this; while (w && w->mParent) { diff --git a/widget/gonk/nsWindow.h b/widget/gonk/nsWindow.h index cf5d140c4ad9..925623a72d6b 100644 --- a/widget/gonk/nsWindow.h +++ b/widget/gonk/nsWindow.h @@ -86,7 +86,7 @@ public: { return NS_OK; } - virtual nsIntPoint WidgetToScreenOffset(); + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); void DispatchTouchInputViaAPZ(mozilla::MultiTouchInput& aInput); NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus); diff --git a/widget/gtk/nsDragService.cpp b/widget/gtk/nsDragService.cpp index 3fe0abb39bf6..cc16157ea81c 100644 --- a/widget/gtk/nsDragService.cpp +++ b/widget/gtk/nsDragService.cpp @@ -1755,7 +1755,7 @@ nsDragService::ScheduleDropEvent(nsWindow *aWindow, return FALSE; } - SetDragEndPoint(aWindowPoint + aWindow->WidgetToScreenOffset()); + SetDragEndPoint(aWindowPoint + aWindow->WidgetToScreenOffsetUntyped()); // We'll reply with gtk_drag_finish(). return TRUE; diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index cf945b0765d0..f37863dd864d 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -1473,10 +1473,10 @@ nsWindow::GetScreenBounds(nsIntRect &aRect) // use the point including window decorations gint x, y; gdk_window_get_root_origin(gtk_widget_get_window(GTK_WIDGET(mContainer)), &x, &y); - aRect.MoveTo(GdkPointToDevicePixels({ x, y })); + aRect.MoveTo(LayoutDevicePixel::ToUntyped(GdkPointToDevicePixels({ x, y }))); } else { - aRect.MoveTo(WidgetToScreenOffset()); + aRect.MoveTo(WidgetToScreenOffsetUntyped()); } // mBounds.Size() is the window bounds, not the window-manager frame // bounds (bug 581863). gdk_window_get_frame_extents would give the @@ -1797,7 +1797,7 @@ nsWindow::SetIcon(const nsAString& aIconSpec) } -nsIntPoint +LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() { gint x = 0, y = 0; @@ -2617,8 +2617,7 @@ nsWindow::OnMotionNotifyEvent(GdkEventMotion *aEvent) } else { LayoutDeviceIntPoint point(NSToIntFloor(aEvent->x_root), NSToIntFloor(aEvent->y_root)); - event.refPoint = point - - LayoutDeviceIntPoint::FromUntyped(WidgetToScreenOffset()); + event.refPoint = point - WidgetToScreenOffset(); } modifierState = aEvent->state; @@ -2696,8 +2695,7 @@ nsWindow::InitButtonEvent(WidgetMouseEvent& aEvent, } else { LayoutDeviceIntPoint point(NSToIntFloor(aGdkEvent->x_root), NSToIntFloor(aGdkEvent->y_root)); - aEvent.refPoint = point - - LayoutDeviceIntPoint::FromUntyped(WidgetToScreenOffset()); + aEvent.refPoint = point - WidgetToScreenOffset(); } guint modifierState = aGdkEvent->state; @@ -3209,8 +3207,7 @@ nsWindow::OnScrollEvent(GdkEventScroll *aEvent) // coordinates relative to this widget. LayoutDeviceIntPoint point(NSToIntFloor(aEvent->x_root), NSToIntFloor(aEvent->y_root)); - wheelEvent.refPoint = point - - LayoutDeviceIntPoint::FromUntyped(WidgetToScreenOffset()); + wheelEvent.refPoint = point - WidgetToScreenOffset(); } KeymapWrapper::InitInputEvent(wheelEvent, aEvent->state); @@ -6338,7 +6335,7 @@ nsWindow::GetDragInfo(WidgetMouseEvent* aMouseEvent, // moved since the mousedown. (On the other hand, it's quite likely // that the mouse has moved, which is why we use the mouse position // from the event.) - nsIntPoint offset = aMouseEvent->widget->WidgetToScreenOffset(); + LayoutDeviceIntPoint offset = aMouseEvent->widget->WidgetToScreenOffset(); *aRootX = aMouseEvent->refPoint.x + offset.x; *aRootY = aMouseEvent->refPoint.y + offset.y; @@ -6499,11 +6496,11 @@ nsWindow::GdkCoordToDevicePixels(gint coord) { return coord * GdkScaleFactor(); } -nsIntPoint +LayoutDeviceIntPoint nsWindow::GdkPointToDevicePixels(GdkPoint point) { gint scale = GdkScaleFactor(); - return nsIntPoint(point.x * scale, - point.y * scale); + return LayoutDeviceIntPoint(point.x * scale, + point.y * scale); } nsIntRect diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index f86650366278..456e2bf2a39e 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -138,7 +138,7 @@ public: NS_IMETHOD SetTitle(const nsAString& aTitle) MOZ_OVERRIDE; NS_IMETHOD SetIcon(const nsAString& aIconSpec) MOZ_OVERRIDE; NS_IMETHOD SetWindowClass(const nsAString& xulWinType) MOZ_OVERRIDE; - virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; NS_IMETHOD EnableDragDrop(bool aEnable) MOZ_OVERRIDE; NS_IMETHOD CaptureMouse(bool aCapture) MOZ_OVERRIDE; NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index ee76fed042fa..2983a6158bb9 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -1668,12 +1668,16 @@ class nsIWidget : public nsISupports { NS_IMETHOD SetIcon(const nsAString& anIconSpec) = 0; /** - * Return this widget's origin in screen coordinates. + * Return this widget's origin in screen coordinates. The untyped version + * exists temporarily to ease conversion to typed coordinates. * * @return screen coordinates stored in the x,y members */ - virtual nsIntPoint WidgetToScreenOffset() = 0; + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() = 0; + virtual nsIntPoint WidgetToScreenOffsetUntyped() { + return mozilla::LayoutDeviceIntPoint::ToUntyped(WidgetToScreenOffset()); + } /** * Given the specified client size, return the corresponding window size, diff --git a/widget/qt/nsWindow.cpp b/widget/qt/nsWindow.cpp index 193d39e22bef..680356b530b0 100644 --- a/widget/qt/nsWindow.cpp +++ b/widget/qt/nsWindow.cpp @@ -626,7 +626,7 @@ nsWindow::Invalidate(const nsIntRect &aRect) return NS_OK; } -nsIntPoint +LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() { NS_ENSURE_TRUE(mWidget, nsIntPoint(0,0)); @@ -634,7 +634,7 @@ nsWindow::WidgetToScreenOffset() QPoint origin(0, 0); origin = mWidget->mapToGlobal(origin); - return nsIntPoint(origin.x(), origin.y()); + return LayoutDeviceIntPoint(origin.x(), origin.y()); } void* diff --git a/widget/qt/nsWindow.h b/widget/qt/nsWindow.h index 70db05e60870..bf970a091205 100644 --- a/widget/qt/nsWindow.h +++ b/widget/qt/nsWindow.h @@ -124,7 +124,7 @@ public: { return NS_OK; } - virtual nsIntPoint WidgetToScreenOffset(); + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus); NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, diff --git a/widget/windows/nsIMM32Handler.cpp b/widget/windows/nsIMM32Handler.cpp index 6aaae7bc45a7..21834da35ba4 100644 --- a/widget/windows/nsIMM32Handler.cpp +++ b/widget/windows/nsIMM32Handler.cpp @@ -1957,7 +1957,7 @@ nsIMM32Handler::SetIMERelatedWindowsPosOnPlugin(nsWindow* aWindow, // window needs to be specified the position in the client area. nsWindow* toplevelWindow = aWindow->GetTopLevelWindow(false); nsIntRect pluginRectInScreen = - editorRectEvent.mReply.mRect + toplevelWindow->WidgetToScreenOffset(); + editorRectEvent.mReply.mRect + toplevelWindow->WidgetToScreenOffsetUntyped(); nsIntRect winRectInScreen; aWindow->GetClientBounds(winRectInScreen); // composition window cannot be positioned on the edge of client area. @@ -1974,7 +1974,7 @@ nsIMM32Handler::SetIMERelatedWindowsPosOnPlugin(nsWindow* aWindow, int32_t yMost = std::min(pluginRectInScreen.YMost(), winRectInScreen.YMost()); clippedPluginRect.width = std::max(0, xMost - clippedPluginRect.x); clippedPluginRect.height = std::max(0, yMost - clippedPluginRect.y); - clippedPluginRect -= aWindow->WidgetToScreenOffset(); + clippedPluginRect -= aWindow->WidgetToScreenOffsetUntyped(); // Cover the plugin with native caret. This prevents IME's window and plugin // overlap. @@ -2013,10 +2013,10 @@ nsIMM32Handler::ResolveIMECaretPos(nsIWidget* aReferenceWidget, return; if (aReferenceWidget) - aOutRect.MoveBy(aReferenceWidget->WidgetToScreenOffset()); + aOutRect.MoveBy(aReferenceWidget->WidgetToScreenOffsetUntyped()); if (aNewOriginWidget) - aOutRect.MoveBy(-aNewOriginWidget->WidgetToScreenOffset()); + aOutRect.MoveBy(-aNewOriginWidget->WidgetToScreenOffsetUntyped()); } /* static */ nsresult diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index 8156c4248d47..ae7d53a8b0fb 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -3198,7 +3198,7 @@ nsTextStore::GetTextExt(TsViewCookie vcView, return E_FAIL; } - event.mReply.mRect.MoveBy(refWindow->WidgetToScreenOffset()); + event.mReply.mRect.MoveBy(refWindow->WidgetToScreenOffsetUntyped()); } // get bounding screen rect to test for clipping @@ -3336,7 +3336,7 @@ nsTextStore::GetScreenExtInternal(RECT &aScreenExt) // Clip frame rect to window rect boundRect.IntersectRect(event.mReply.mRect, boundRect); if (!boundRect.IsEmpty()) { - boundRect.MoveBy(refWindow->WidgetToScreenOffset()); + boundRect.MoveBy(refWindow->WidgetToScreenOffsetUntyped()); ::SetRect(&aScreenExt, boundRect.x, boundRect.y, boundRect.XMost(), boundRect.YMost()); } else { @@ -4325,8 +4325,8 @@ nsTextStore::CreateNativeCaret() } if (toplevelWindow != window) { - caretRect.MoveBy(toplevelWindow->WidgetToScreenOffset()); - caretRect.MoveBy(-window->WidgetToScreenOffset()); + caretRect.MoveBy(toplevelWindow->WidgetToScreenOffsetUntyped()); + caretRect.MoveBy(-window->WidgetToScreenOffsetUntyped()); } ::SetCaretPos(caretRect.x, caretRect.y); diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 5bd07ff155e4..46340afd430a 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -1991,7 +1991,7 @@ nsIntPoint nsWindow::GetClientOffset() RECT r1; GetWindowRect(mWnd, &r1); - nsIntPoint pt = WidgetToScreenOffset(); + LayoutDeviceIntPoint pt = WidgetToScreenOffset(); return nsIntPoint(pt.x - r1.left, pt.y - r1.top); } @@ -3061,13 +3061,13 @@ NS_METHOD nsWindow::SetIcon(const nsAString& aIconSpec) * **************************************************************/ -nsIntPoint nsWindow::WidgetToScreenOffset() +LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() { POINT point; point.x = 0; point.y = 0; ::ClientToScreen(mWnd, &point); - return nsIntPoint(point.x, point.y); + return LayoutDeviceIntPoint(point.x, point.y); } nsIntSize nsWindow::ClientToWindowSize(const nsIntSize& aClientSize) @@ -3819,7 +3819,7 @@ bool nsWindow::DispatchMouseEvent(uint32_t aEventType, WPARAM wParam, aInputSource == nsIDOMMouseEvent::MOZ_SOURCE_PEN || !(WinUtils::GetIsMouseFromTouch(aEventType) && mTouchWindow); - nsIntPoint mpScreen = eventPoint + WidgetToScreenOffset(); + nsIntPoint mpScreen = eventPoint + WidgetToScreenOffsetUntyped(); // Suppress mouse moves caused by widget creation if (aEventType == NS_MOUSE_MOVE) diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index e580254debe0..d76931dd8240 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -136,7 +136,7 @@ public: virtual void FreeNativeData(void * data, uint32_t aDataType); NS_IMETHOD SetTitle(const nsAString& aTitle); NS_IMETHOD SetIcon(const nsAString& aIconSpec); - virtual nsIntPoint WidgetToScreenOffset(); + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); virtual nsIntSize ClientToWindowSize(const nsIntSize& aClientSize); NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus); diff --git a/widget/windows/winrt/MetroWidget.cpp b/widget/windows/winrt/MetroWidget.cpp index 2c4ad6e06035..a194f1286632 100644 --- a/widget/windows/winrt/MetroWidget.cpp +++ b/widget/windows/winrt/MetroWidget.cpp @@ -1492,10 +1492,10 @@ MetroWidget::SetTitle(const nsAString& aTitle) return NS_OK; } -nsIntPoint +LayoutDeviceIntPoint MetroWidget::WidgetToScreenOffset() { - return nsIntPoint(0,0); + return LayoutDeviceIntPoint(0,0); } NS_IMETHODIMP diff --git a/widget/windows/winrt/MetroWidget.h b/widget/windows/winrt/MetroWidget.h index 74742d98705a..bd6c2d465663 100644 --- a/widget/windows/winrt/MetroWidget.h +++ b/widget/windows/winrt/MetroWidget.h @@ -172,7 +172,7 @@ public: virtual nsresult ConfigureChildren(const nsTArray& aConfigurations); virtual void* GetNativeData(uint32_t aDataType); virtual void FreeNativeData(void * data, uint32_t aDataType); - virtual nsIntPoint WidgetToScreenOffset(); + virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); already_AddRefed GetPresShell(); From 7b3840d6429fd9960fed7ee06020392c5497850c Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Sun, 1 Feb 2015 15:27:14 -0800 Subject: [PATCH 07/16] Back out 5167196c4b98 (bug 1125040) for not compiling on Linux CLOSED TREE --- accessible/generic/HyperTextAccessible.cpp | 2 +- dom/base/nsDOMWindowUtils.cpp | 3 ++- dom/base/nsQueryContentEventResult.cpp | 4 ++-- dom/events/ContentEventHandler.cpp | 8 +++++--- dom/events/Event.cpp | 3 ++- dom/events/EventStateManager.cpp | 21 +++++++++++-------- dom/events/IMEContentObserver.cpp | 9 ++++---- dom/events/UIEvent.h | 3 ++- dom/events/WheelHandlingHelper.cpp | 4 ++-- dom/plugins/base/nsPluginInstanceOwner.cpp | 3 ++- embedding/browser/nsDocShellTreeOwner.cpp | 2 +- gfx/tests/gtest/TestCompositor.cpp | 2 +- layout/base/PositionedEventTargeting.cpp | 4 ++-- layout/base/nsLayoutUtils.cpp | 24 +++++++++++----------- layout/base/nsLayoutUtils.h | 7 +++---- layout/base/nsPresShell.cpp | 4 ++-- layout/generic/nsFrame.cpp | 2 +- layout/xul/nsResizerFrame.cpp | 6 ++++-- layout/xul/nsXULPopupManager.cpp | 2 +- view/nsView.cpp | 2 +- widget/PuppetWidget.h | 4 ++-- widget/android/AndroidJavaWrappers.cpp | 7 ++++--- widget/android/nsWindow.cpp | 9 ++++---- widget/android/nsWindow.h | 2 +- widget/cocoa/nsChildView.h | 2 +- widget/cocoa/nsChildView.mm | 10 ++++----- widget/cocoa/nsCocoaWindow.h | 2 +- widget/cocoa/nsCocoaWindow.mm | 6 +++--- widget/gonk/nsWindow.cpp | 4 ++-- widget/gonk/nsWindow.h | 2 +- widget/gtk/nsDragService.cpp | 2 +- widget/gtk/nsWindow.cpp | 23 ++++++++++++--------- widget/gtk/nsWindow.h | 2 +- widget/nsIWidget.h | 8 ++------ widget/qt/nsWindow.cpp | 4 ++-- widget/qt/nsWindow.h | 2 +- widget/windows/nsIMM32Handler.cpp | 8 ++++---- widget/windows/nsTextStore.cpp | 8 ++++---- widget/windows/nsWindow.cpp | 8 ++++---- widget/windows/nsWindow.h | 2 +- widget/windows/winrt/MetroWidget.cpp | 4 ++-- widget/windows/winrt/MetroWidget.h | 2 +- 42 files changed, 124 insertions(+), 112 deletions(-) diff --git a/accessible/generic/HyperTextAccessible.cpp b/accessible/generic/HyperTextAccessible.cpp index 5681aa01331e..3d394e24a0fc 100644 --- a/accessible/generic/HyperTextAccessible.cpp +++ b/accessible/generic/HyperTextAccessible.cpp @@ -1344,7 +1344,7 @@ HyperTextAccessible::GetCaretRect(nsIWidget** aWidget) nsIntRect caretRect; caretRect = rect.ToOutsidePixels(frame->PresContext()->AppUnitsPerDevPixel()); // ((content screen origin) - (content offset in the widget)) = widget origin on the screen - caretRect.MoveBy((*aWidget)->WidgetToScreenOffsetUntyped() - (*aWidget)->GetClientOffset()); + caretRect.MoveBy((*aWidget)->WidgetToScreenOffset() - (*aWidget)->GetClientOffset()); // Correct for character size, so that caret always matches the size of // the character. This is important for font size transitions, and is diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 6787241774cc..638b13eabf63 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2195,7 +2195,8 @@ nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType, } } - pt += widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset(); + pt += LayoutDeviceIntPoint::FromUntyped( + widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset()); WidgetQueryContentEvent queryEvent(true, aType, targetWidget); InitEvent(queryEvent, &pt); diff --git a/dom/base/nsQueryContentEventResult.cpp b/dom/base/nsQueryContentEventResult.cpp index c451952a03f9..bd2b7aee63b4 100644 --- a/dom/base/nsQueryContentEventResult.cpp +++ b/dom/base/nsQueryContentEventResult.cpp @@ -147,7 +147,7 @@ nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget, } // Convert the top widget related coordinates to the given widget's. - LayoutDeviceIntPoint offset = + nsIntPoint offset = aWidget->WidgetToScreenOffset() - topWidget->WidgetToScreenOffset(); - mRect.MoveBy(-LayoutDeviceIntPoint::ToUntyped(offset)); + mRect.MoveBy(-offset); } diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp index 3c3665a50a93..f5e83a2e89b2 100644 --- a/dom/events/ContentEventHandler.cpp +++ b/dom/events/ContentEventHandler.cpp @@ -1149,8 +1149,9 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent) eventOnRoot.mUseNativeLineBreak = aEvent->mUseNativeLineBreak; eventOnRoot.refPoint = aEvent->refPoint; if (rootWidget != aEvent->widget) { - eventOnRoot.refPoint += aEvent->widget->WidgetToScreenOffset() - - rootWidget->WidgetToScreenOffset(); + eventOnRoot.refPoint += LayoutDeviceIntPoint::FromUntyped( + aEvent->widget->WidgetToScreenOffset() - + rootWidget->WidgetToScreenOffset()); } nsPoint ptInRoot = nsLayoutUtils::GetEventCoordinatesRelativeTo(&eventOnRoot, rootFrame); @@ -1213,7 +1214,8 @@ ContentEventHandler::OnQueryDOMWidgetHittest(WidgetQueryContentEvent* aEvent) nsIFrame* docFrame = mPresShell->GetRootFrame(); NS_ENSURE_TRUE(docFrame, NS_ERROR_FAILURE); - LayoutDeviceIntPoint eventLoc = aEvent->refPoint + aEvent->widget->WidgetToScreenOffset(); + LayoutDeviceIntPoint eventLoc = aEvent->refPoint + + LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); nsIntRect docFrameRect = docFrame->GetScreenRect(); // Returns CSS pixels CSSIntPoint eventLocCSS( mPresContext->DevPixelsToIntCSSPixels(eventLoc.x) - docFrameRect.x, diff --git a/dom/events/Event.cpp b/dom/events/Event.cpp index 04dbbf56b062..e7d967814d34 100644 --- a/dom/events/Event.cpp +++ b/dom/events/Event.cpp @@ -902,7 +902,8 @@ Event::GetScreenCoords(nsPresContext* aPresContext, return LayoutDeviceIntPoint::ToUntyped(aPoint); } - LayoutDeviceIntPoint offset = aPoint + guiEvent->widget->WidgetToScreenOffset(); + LayoutDeviceIntPoint offset = aPoint + + LayoutDeviceIntPoint::FromUntyped(guiEvent->widget->WidgetToScreenOffset()); nscoord factor = aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom(); return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor), diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index 81dd8ad630f8..371990d1b8b1 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -1505,7 +1505,8 @@ EventStateManager::BeginTrackingDragGesture(nsPresContext* aPresContext, // Note that |inDownEvent| could be either a mouse down event or a // synthesized mouse move event. - mGestureDownPoint = inDownEvent->refPoint + inDownEvent->widget->WidgetToScreenOffset(); + mGestureDownPoint = inDownEvent->refPoint + + LayoutDeviceIntPoint::FromUntyped(inDownEvent->widget->WidgetToScreenOffset()); inDownFrame->GetContentForEvent(inDownEvent, getter_AddRefs(mGestureDownContent)); @@ -1543,7 +1544,8 @@ EventStateManager::FillInEventFromGestureDown(WidgetMouseEvent* aEvent) // Set the coordinates in the new event to the coordinates of // the old event, adjusted for the fact that the widget might be // different - aEvent->refPoint = mGestureDownPoint - aEvent->widget->WidgetToScreenOffset(); + aEvent->refPoint = mGestureDownPoint - + LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); aEvent->modifiers = mGestureModifiers; aEvent->buttons = mGestureDownButtons; } @@ -1599,7 +1601,8 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext, } // fire drag gesture if mouse has moved enough - LayoutDeviceIntPoint pt = aEvent->refPoint + aEvent->widget->WidgetToScreenOffset(); + LayoutDeviceIntPoint pt = aEvent->refPoint + + LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); LayoutDeviceIntPoint distance = pt - mGestureDownPoint; if (Abs(distance.x) > AssertedCast(pixelThresholdX) || Abs(distance.y) > AssertedCast(pixelThresholdY)) { @@ -3213,9 +3216,9 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext, WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent(); event.refPoint = mouseEvent->refPoint; if (mouseEvent->widget) { - event.refPoint += mouseEvent->widget->WidgetToScreenOffset(); + event.refPoint += LayoutDeviceIntPoint::FromUntyped(mouseEvent->widget->WidgetToScreenOffset()); } - event.refPoint -= widget->WidgetToScreenOffset(); + event.refPoint -= LayoutDeviceIntPoint::FromUntyped(widget->WidgetToScreenOffset()); event.modifiers = mouseEvent->modifiers; event.buttons = mouseEvent->buttons; event.inputSource = mouseEvent->inputSource; @@ -4020,8 +4023,8 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent) // in the other branch here. sSynthCenteringPoint = center; aMouseEvent->widget->SynthesizeNativeMouseMove( - LayoutDeviceIntPoint::ToUntyped(center + - aMouseEvent->widget->WidgetToScreenOffset())); + LayoutDeviceIntPoint::ToUntyped(center) + + aMouseEvent->widget->WidgetToScreenOffset()); } else if (aMouseEvent->refPoint == sSynthCenteringPoint) { // This is the "synthetic native" event we dispatched to re-center the // pointer. Cancel it so we don't expose the centering move to content. @@ -4157,7 +4160,7 @@ EventStateManager::SetPointerLock(nsIWidget* aWidget, aWidget, mPresContext); aWidget->SynthesizeNativeMouseMove( - LayoutDeviceIntPoint::ToUntyped(sLastRefPoint + aWidget->WidgetToScreenOffset())); + LayoutDeviceIntPoint::ToUntyped(sLastRefPoint) + aWidget->WidgetToScreenOffset()); // Retarget all events to this element via capture. nsIPresShell::SetCapturingContent(aElement, CAPTURE_POINTERLOCK); @@ -4173,7 +4176,7 @@ EventStateManager::SetPointerLock(nsIWidget* aWidget, // no movement. sLastRefPoint = mPreLockPoint; aWidget->SynthesizeNativeMouseMove( - LayoutDeviceIntPoint::ToUntyped(mPreLockPoint + aWidget->WidgetToScreenOffset())); + LayoutDeviceIntPoint::ToUntyped(mPreLockPoint) + aWidget->WidgetToScreenOffset()); // Don't retarget events to this element any more. nsIPresShell::SetCapturingContent(nullptr, CAPTURE_POINTERLOCK); diff --git a/dom/events/IMEContentObserver.cpp b/dom/events/IMEContentObserver.cpp index ac9de57b071e..836c6882abce 100644 --- a/dom/events/IMEContentObserver.cpp +++ b/dom/events/IMEContentObserver.cpp @@ -449,14 +449,15 @@ IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext, nsIWidget* topLevelWidget = mWidget->GetTopLevelWidget(); if (topLevelWidget && topLevelWidget != mWidget) { charAtPt.mReply.mRect.MoveBy( - topLevelWidget->WidgetToScreenOffsetUntyped() - - mWidget->WidgetToScreenOffsetUntyped()); + topLevelWidget->WidgetToScreenOffset() - + mWidget->WidgetToScreenOffset()); } // The refPt is relative to its widget. // We should notify it with offset in the widget. if (aMouseEvent->widget != mWidget) { - charAtPt.refPoint += aMouseEvent->widget->WidgetToScreenOffset() - - mWidget->WidgetToScreenOffset(); + charAtPt.refPoint += LayoutDeviceIntPoint::FromUntyped( + aMouseEvent->widget->WidgetToScreenOffset() - + mWidget->WidgetToScreenOffset()); } IMENotification notification(NOTIFY_IME_OF_MOUSE_BUTTON_EVENT); diff --git a/dom/events/UIEvent.h b/dom/events/UIEvent.h index 81b6097286b8..d13dc7880199 100644 --- a/dom/events/UIEvent.h +++ b/dom/events/UIEvent.h @@ -57,7 +57,8 @@ public: return LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint); } - LayoutDeviceIntPoint offset = aEvent->refPoint + event->widget->WidgetToScreenOffset(); + LayoutDeviceIntPoint offset = aEvent->refPoint + + LayoutDeviceIntPoint::FromUntyped(event->widget->WidgetToScreenOffset()); nscoord factor = aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom(); return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor), diff --git a/dom/events/WheelHandlingHelper.cpp b/dom/events/WheelHandlingHelper.cpp index 35441dd930a9..ba586cfc3684 100644 --- a/dom/events/WheelHandlingHelper.cpp +++ b/dom/events/WheelHandlingHelper.cpp @@ -293,8 +293,8 @@ WheelTransaction::GetScreenPoint(WidgetGUIEvent* aEvent) { NS_ASSERTION(aEvent, "aEvent is null"); NS_ASSERTION(aEvent->widget, "aEvent-widget is null"); - return LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint + - aEvent->widget->WidgetToScreenOffset()); + return LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint) + + aEvent->widget->WidgetToScreenOffset(); } /* static */ uint32_t diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index e3c6e1ef5787..13f8d8484bfb 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -2121,7 +2121,8 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent) // Get reference point relative to screen: LayoutDeviceIntPoint rootPoint(-1, -1); if (widget) - rootPoint = anEvent.refPoint + widget->WidgetToScreenOffset(); + rootPoint = anEvent.refPoint + + LayoutDeviceIntPoint::FromUntyped(widget->WidgetToScreenOffset()); #ifdef MOZ_WIDGET_GTK Window root = GDK_ROOT_WINDOW(); #elif defined(MOZ_WIDGET_QT) diff --git a/embedding/browser/nsDocShellTreeOwner.cpp b/embedding/browser/nsDocShellTreeOwner.cpp index 4787a2c2408a..e4490a61e9ee 100644 --- a/embedding/browser/nsDocShellTreeOwner.cpp +++ b/embedding/browser/nsDocShellTreeOwner.cpp @@ -1452,7 +1452,7 @@ ChromeTooltipListener::sTooltipCallback(nsITimer *aTimer, if (textFound) { nsString tipText(tooltipText); - LayoutDeviceIntPoint screenDot = widget->WidgetToScreenOffset(); + nsIntPoint screenDot = widget->WidgetToScreenOffset(); self->ShowTooltip(self->mMouseScreenX - screenDot.x, self->mMouseScreenY - screenDot.y, tipText); diff --git a/gfx/tests/gtest/TestCompositor.cpp b/gfx/tests/gtest/TestCompositor.cpp index a8cf3c2674b9..cf0b9bf3664f 100644 --- a/gfx/tests/gtest/TestCompositor.cpp +++ b/gfx/tests/gtest/TestCompositor.cpp @@ -71,7 +71,7 @@ public: virtual nsresult ConfigureChildren(const nsTArray& aConfigurations) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD Invalidate(const nsIntRect &aRect) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD SetTitle(const nsAString& title) MOZ_OVERRIDE { return NS_OK; } - virtual LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE { return LayoutDeviceIntPoint(0, 0); } + virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE { return nsIntPoint(0, 0); } NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus) MOZ_OVERRIDE { return NS_OK; } NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, bool aDoCapture) MOZ_OVERRIDE { return NS_OK; } diff --git a/layout/base/PositionedEventTargeting.cpp b/layout/base/PositionedEventTargeting.cpp index 21c87473ab74..99c26818c864 100644 --- a/layout/base/PositionedEventTargeting.cpp +++ b/layout/base/PositionedEventTargeting.cpp @@ -473,11 +473,11 @@ FindFrameTargetedByInputEvent(WidgetGUIEvent* aEvent, if (!view) { return target; } - LayoutDeviceIntPoint widgetPoint = nsLayoutUtils::TranslateViewToWidget( + nsIntPoint widgetPoint = nsLayoutUtils::TranslateViewToWidget( aRootFrame->PresContext(), view, point, aEvent->widget); if (widgetPoint.x != NS_UNCONSTRAINEDSIZE) { // If that succeeded, we update the point in the event - aEvent->refPoint = widgetPoint; + aEvent->refPoint = LayoutDeviceIntPoint::FromUntyped(widgetPoint); } return target; } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 8fe15aef9ff9..47812759ce52 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -2627,8 +2627,8 @@ nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame, NSFloatPixelsToAppUnits(float(result.height), destAppUnitsPerDevPixel)); } -static LayoutDeviceIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) { - LayoutDeviceIntPoint offset(0, 0); +static nsIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) { + nsIntPoint offset(0, 0); while ((aWidget->WindowType() == eWindowType_child || aWidget->IsPlugin())) { nsIWidget* parent = aWidget->GetParent(); @@ -2637,19 +2637,18 @@ static LayoutDeviceIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRoo } nsIntRect bounds; aWidget->GetBounds(bounds); - offset += LayoutDeviceIntPoint::FromUntyped(bounds.TopLeft()); + offset += bounds.TopLeft(); aWidget = parent; } aRootWidget = aWidget; return offset; } -static LayoutDeviceIntPoint -WidgetToWidgetOffset(nsIWidget* aFrom, nsIWidget* aTo) { +static nsIntPoint WidgetToWidgetOffset(nsIWidget* aFrom, nsIWidget* aTo) { nsIWidget* fromRoot; - LayoutDeviceIntPoint fromOffset = GetWidgetOffset(aFrom, fromRoot); + nsIntPoint fromOffset = GetWidgetOffset(aFrom, fromRoot); nsIWidget* toRoot; - LayoutDeviceIntPoint toOffset = GetWidgetOffset(aTo, toRoot); + nsIntPoint toOffset = GetWidgetOffset(aTo, toRoot); if (fromRoot == toRoot) { return fromOffset - toOffset; @@ -2668,13 +2667,14 @@ nsLayoutUtils::TranslateWidgetToView(nsPresContext* aPresContext, return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); } - LayoutDeviceIntPoint widgetPoint = aPt + WidgetToWidgetOffset(aWidget, viewWidget); + LayoutDeviceIntPoint widgetPoint = aPt + + LayoutDeviceIntPoint::FromUntyped(WidgetToWidgetOffset(aWidget, viewWidget)); nsPoint widgetAppUnits(aPresContext->DevPixelsToAppUnits(widgetPoint.x), aPresContext->DevPixelsToAppUnits(widgetPoint.y)); return widgetAppUnits - viewOffset; } -LayoutDeviceIntPoint +nsIntPoint nsLayoutUtils::TranslateViewToWidget(nsPresContext* aPresContext, nsView* aView, nsPoint aPt, nsIWidget* aWidget) @@ -2682,11 +2682,11 @@ nsLayoutUtils::TranslateViewToWidget(nsPresContext* aPresContext, nsPoint viewOffset; nsIWidget* viewWidget = aView->GetNearestWidget(&viewOffset); if (!viewWidget) { - return LayoutDeviceIntPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); + return nsIntPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); } - LayoutDeviceIntPoint relativeToViewWidget(aPresContext->AppUnitsToDevPixels(aPt.x + viewOffset.x), - aPresContext->AppUnitsToDevPixels(aPt.y + viewOffset.y)); + nsIntPoint relativeToViewWidget(aPresContext->AppUnitsToDevPixels(aPt.x + viewOffset.x), + aPresContext->AppUnitsToDevPixels(aPt.y + viewOffset.y)); return relativeToViewWidget + WidgetToWidgetOffset(viewWidget, aWidget); } diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index e733e72ebdff..d2a034725117 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -728,10 +728,9 @@ public: * @param aWidget the widget to which returned coordinates are relative * @return the point in the view's coordinates */ - static mozilla::LayoutDeviceIntPoint - TranslateViewToWidget(nsPresContext* aPresContext, - nsView* aView, nsPoint aPt, - nsIWidget* aWidget); + static nsIntPoint TranslateViewToWidget(nsPresContext* aPresContext, + nsView* aView, nsPoint aPt, + nsIWidget* aWidget); enum FrameForPointFlags { /** diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 4f1c7bd62a80..78d299df0694 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -8474,9 +8474,9 @@ PresShell::AdjustContextMenuKeyEvent(WidgetMouseEvent* aEvent) nsCOMPtr widget = popupFrame->GetNearestWidget(); aEvent->widget = widget; - LayoutDeviceIntPoint widgetPoint = widget->WidgetToScreenOffset(); + nsIntPoint widgetPoint = widget->WidgetToScreenOffset(); aEvent->refPoint = LayoutDeviceIntPoint::FromUntyped( - itemFrame->GetScreenRect().BottomLeft()) - widgetPoint; + itemFrame->GetScreenRect().BottomLeft() - widgetPoint); mCurrentEventContent = itemFrame->GetContent(); mCurrentEventFrame = itemFrame; diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index cd4b0f7376b7..a26dff22b199 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4812,7 +4812,7 @@ nsRect nsIFrame::GetScreenRectInAppUnits() const nsCOMPtr rootWidget; presContext->PresShell()->GetViewManager()->GetRootWidget(getter_AddRefs(rootWidget)); if (rootWidget) { - LayoutDeviceIntPoint rootDevPx = rootWidget->WidgetToScreenOffset(); + nsIntPoint rootDevPx = rootWidget->WidgetToScreenOffset(); rootScreenPos.x = presContext->DevPixelsToAppUnits(rootDevPx.x); rootScreenPos.y = presContext->DevPixelsToAppUnits(rootDevPx.y); } diff --git a/layout/xul/nsResizerFrame.cpp b/layout/xul/nsResizerFrame.cpp index afdab2b22911..228fbd77ae09 100644 --- a/layout/xul/nsResizerFrame.cpp +++ b/layout/xul/nsResizerFrame.cpp @@ -117,7 +117,8 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, LayoutDeviceIntPoint refPoint; if (!GetEventPoint(aEvent, refPoint)) return NS_OK; - mMouseDownPoint = refPoint + aEvent->widget->WidgetToScreenOffset(); + mMouseDownPoint = refPoint + + LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); // we're tracking mTrackingMouseMove = true; @@ -165,7 +166,8 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, LayoutDeviceIntPoint refPoint; if (!GetEventPoint(aEvent, refPoint)) return NS_OK; - LayoutDeviceIntPoint screenPoint = refPoint + aEvent->widget->WidgetToScreenOffset(); + LayoutDeviceIntPoint screenPoint = refPoint + + LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); LayoutDeviceIntPoint mouseMove(screenPoint - mMouseDownPoint); // Determine which direction to resize by checking the dir attribute. diff --git a/layout/xul/nsXULPopupManager.cpp b/layout/xul/nsXULPopupManager.cpp index eb5e7b1ae0cb..220749bedc28 100644 --- a/layout/xul/nsXULPopupManager.cpp +++ b/layout/xul/nsXULPopupManager.cpp @@ -729,7 +729,7 @@ nsXULPopupManager::ShowTooltipAtScreen(nsIContent* aPopup, if (rootPresContext) { nsIWidget *rootWidget = rootPresContext->GetRootWidget(); if (rootWidget) { - mCachedMousePoint -= rootWidget->WidgetToScreenOffsetUntyped(); + mCachedMousePoint -= rootWidget->WidgetToScreenOffset(); } } diff --git a/view/nsView.cpp b/view/nsView.cpp index 63b0e4ba46ec..7ca917cb8a6e 100644 --- a/view/nsView.cpp +++ b/view/nsView.cpp @@ -220,7 +220,7 @@ nsIntRect nsView::CalcWidgetBounds(nsWindowType aType) if (parentWidget && aType == eWindowType_popup && IsEffectivelyVisible()) { // put offset into screen coordinates. (based on client area origin) - LayoutDeviceIntPoint screenPoint = parentWidget->WidgetToScreenOffset(); + nsIntPoint screenPoint = parentWidget->WidgetToScreenOffset(); viewBounds += nsPoint(NSIntPixelsToAppUnits(screenPoint.x, p2a), NSIntPixelsToAppUnits(screenPoint.y, p2a)); } diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index 95f9b77083f5..d9c5dd6d00bf 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -126,8 +126,8 @@ public: { return NS_ERROR_UNEXPECTED; } // PuppetWidgets are always at <0, 0>. - virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE - { return mozilla::LayoutDeviceIntPoint(0, 0); } + virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE + { return nsIntPoint(0, 0); } void InitEvent(WidgetGUIEvent& aEvent, nsIntPoint* aPoint = nullptr); diff --git a/widget/android/AndroidJavaWrappers.cpp b/widget/android/AndroidJavaWrappers.cpp index 27e9ffed4d75..a3aefec79b24 100644 --- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -730,7 +730,7 @@ AndroidGeckoEvent::MakeTouchEvent(nsIWidget* widget) event.modifiers = DOMModifiers(); event.time = Time(); - const LayoutDeviceIntPoint& offset = widget->WidgetToScreenOffset(); + const nsIntPoint& offset = widget->WidgetToScreenOffset(); event.touches.SetCapacity(endIndex - startIndex); for (int i = startIndex; i < endIndex; i++) { // In this code branch, we are dispatching this event directly @@ -796,7 +796,7 @@ AndroidGeckoEvent::MakeMultiTouchInput(nsIWidget* widget) return event; } - const nsIntPoint& offset = widget->WidgetToScreenOffsetUntyped(); + const nsIntPoint& offset = widget->WidgetToScreenOffset(); event.mTouches.SetCapacity(endIndex - startIndex); for (int i = startIndex; i < endIndex; i++) { nsIntPoint point = Points()[i] - offset; @@ -853,10 +853,11 @@ AndroidGeckoEvent::MakeMouseEvent(nsIWidget* widget) // We are dispatching this event directly into Gecko (as opposed to going // through the AsyncPanZoomController), and the Points() array has points // in CSS pixels, which we need to convert to LayoutDevice pixels. - const LayoutDeviceIntPoint& offset = widget->WidgetToScreenOffset(); + const nsIntPoint& offset = widget->WidgetToScreenOffset(); CSSToLayoutDeviceScale scale = widget->GetDefaultScale(); event.refPoint = LayoutDeviceIntPoint((Points()[0].x * scale.scale) - offset.x, (Points()[0].y * scale.scale) - offset.y); + return event; } diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 84edc194d12a..6d7bf270c97d 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -630,7 +630,7 @@ nsWindow::BringToFront() NS_IMETHODIMP nsWindow::GetScreenBounds(nsIntRect &aRect) { - LayoutDeviceIntPoint p = WidgetToScreenOffset(); + nsIntPoint p = WidgetToScreenOffset(); aRect.x = p.x; aRect.y = p.y; @@ -640,10 +640,10 @@ nsWindow::GetScreenBounds(nsIntRect &aRect) return NS_OK; } -LayoutDeviceIntPoint +nsIntPoint nsWindow::WidgetToScreenOffset() { - LayoutDeviceIntPoint p(0, 0); + nsIntPoint p(0, 0); nsWindow *w = this; while (w && !w->IsTopLevel()) { @@ -1041,7 +1041,8 @@ nsWindow::OnContextmenuEvent(AndroidGeckoEvent *ae) WidgetMouseEvent contextMenuEvent(true, NS_CONTEXTMENU, this, WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); contextMenuEvent.refPoint = - RoundedToInt(pt * GetDefaultScale()) - WidgetToScreenOffset(); + LayoutDeviceIntPoint(RoundedToInt(pt * GetDefaultScale())) - + LayoutDeviceIntPoint::FromUntyped(WidgetToScreenOffset()); contextMenuEvent.ignoreRootScrollFrame = true; contextMenuEvent.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h index e21edf050c15..0c8f5d133804 100644 --- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -100,7 +100,7 @@ public: NS_IMETHOD Invalidate(const nsIntRect &aRect); NS_IMETHOD SetFocus(bool aRaise = false); NS_IMETHOD GetScreenBounds(nsIntRect &aRect); - virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); + virtual nsIntPoint WidgetToScreenOffset(); NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus); nsEventStatus DispatchEvent(mozilla::WidgetGUIEvent* aEvent); diff --git a/widget/cocoa/nsChildView.h b/widget/cocoa/nsChildView.h index a1be2604df40..65aaef78f2ff 100644 --- a/widget/cocoa/nsChildView.h +++ b/widget/cocoa/nsChildView.h @@ -401,7 +401,7 @@ public: virtual void* GetNativeData(uint32_t aDataType) MOZ_OVERRIDE; virtual nsresult ConfigureChildren(const nsTArray& aConfigurations) MOZ_OVERRIDE; - virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; + virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; virtual bool ShowsResizeIndicator(nsIntRect* aResizerRect) MOZ_OVERRIDE; static bool ConvertStatus(nsEventStatus aStatus) diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 369eadd17ed3..2bbf250b33e8 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -923,7 +923,7 @@ NS_IMETHODIMP nsChildView::GetClientBounds(nsIntRect &aRect) if (!mParentWidget) { // For top level widgets we want the position on screen, not the position // of this view inside the window. - aRect.MoveTo(WidgetToScreenOffsetUntyped()); + aRect.MoveTo(WidgetToScreenOffset()); } return NS_OK; } @@ -931,7 +931,7 @@ NS_IMETHODIMP nsChildView::GetClientBounds(nsIntRect &aRect) NS_IMETHODIMP nsChildView::GetScreenBounds(nsIntRect &aRect) { GetBounds(aRect); - aRect.MoveTo(WidgetToScreenOffsetUntyped()); + aRect.MoveTo(WidgetToScreenOffset()); return NS_OK; } @@ -1482,7 +1482,7 @@ void nsChildView::ReportSizeEvent() // Return the offset between this child view and the screen. // @return -- widget origin in device-pixel coords -LayoutDeviceIntPoint nsChildView::WidgetToScreenOffset() +nsIntPoint nsChildView::WidgetToScreenOffset() { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; @@ -1500,9 +1500,9 @@ LayoutDeviceIntPoint nsChildView::WidgetToScreenOffset() FlipCocoaScreenCoordinate(origin); // convert to device pixels - return LayoutDeviceIntPoint::FromUntyped(CocoaPointsToDevPixels(origin)); + return CocoaPointsToDevPixels(origin); - NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(LayoutDeviceIntPoint(0,0)); + NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(nsIntPoint(0,0)); } NS_IMETHODIMP nsChildView::CaptureRollupEvents(nsIRollupListener * aListener, diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h index 530f05c4a58d..814cd73b0198 100644 --- a/widget/cocoa/nsCocoaWindow.h +++ b/widget/cocoa/nsCocoaWindow.h @@ -260,7 +260,7 @@ public: NS_IMETHOD SetModal(bool aState) MOZ_OVERRIDE; virtual bool IsVisible() const MOZ_OVERRIDE; NS_IMETHOD SetFocus(bool aState=false) MOZ_OVERRIDE; - virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; + virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; virtual nsIntPoint GetClientOffset() MOZ_OVERRIDE; virtual nsIntSize ClientToWindowSize(const nsIntSize& aClientSize) MOZ_OVERRIDE; diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index f75d2195bc19..d5936bec4786 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -1812,7 +1812,7 @@ NS_IMETHODIMP nsCocoaWindow::SetFocus(bool aState) return NS_OK; } -LayoutDeviceIntPoint nsCocoaWindow::WidgetToScreenOffset() +nsIntPoint nsCocoaWindow::WidgetToScreenOffset() { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; @@ -1823,9 +1823,9 @@ LayoutDeviceIntPoint nsCocoaWindow::WidgetToScreenOffset() } r = nsCocoaUtils::CocoaRectToGeckoRectDevPix(rect, BackingScaleFactor()); - return LayoutDeviceIntPoint::FromUntyped(r.TopLeft()); + return r.TopLeft(); - NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(LayoutDeviceIntPoint(0,0)); + NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(nsIntPoint(0,0)); } nsIntPoint nsCocoaWindow::GetClientOffset() diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index ea9131dccea6..732d3a33e7a5 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -522,10 +522,10 @@ nsWindow::Invalidate(const nsIntRect &aRect) return NS_OK; } -LayoutDeviceIntPoint +nsIntPoint nsWindow::WidgetToScreenOffset() { - LayoutDeviceIntPoint p(0, 0); + nsIntPoint p(0, 0); nsWindow *w = this; while (w && w->mParent) { diff --git a/widget/gonk/nsWindow.h b/widget/gonk/nsWindow.h index 925623a72d6b..cf5d140c4ad9 100644 --- a/widget/gonk/nsWindow.h +++ b/widget/gonk/nsWindow.h @@ -86,7 +86,7 @@ public: { return NS_OK; } - virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); + virtual nsIntPoint WidgetToScreenOffset(); void DispatchTouchInputViaAPZ(mozilla::MultiTouchInput& aInput); NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus); diff --git a/widget/gtk/nsDragService.cpp b/widget/gtk/nsDragService.cpp index cc16157ea81c..3fe0abb39bf6 100644 --- a/widget/gtk/nsDragService.cpp +++ b/widget/gtk/nsDragService.cpp @@ -1755,7 +1755,7 @@ nsDragService::ScheduleDropEvent(nsWindow *aWindow, return FALSE; } - SetDragEndPoint(aWindowPoint + aWindow->WidgetToScreenOffsetUntyped()); + SetDragEndPoint(aWindowPoint + aWindow->WidgetToScreenOffset()); // We'll reply with gtk_drag_finish(). return TRUE; diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index f37863dd864d..cf945b0765d0 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -1473,10 +1473,10 @@ nsWindow::GetScreenBounds(nsIntRect &aRect) // use the point including window decorations gint x, y; gdk_window_get_root_origin(gtk_widget_get_window(GTK_WIDGET(mContainer)), &x, &y); - aRect.MoveTo(LayoutDevicePixel::ToUntyped(GdkPointToDevicePixels({ x, y }))); + aRect.MoveTo(GdkPointToDevicePixels({ x, y })); } else { - aRect.MoveTo(WidgetToScreenOffsetUntyped()); + aRect.MoveTo(WidgetToScreenOffset()); } // mBounds.Size() is the window bounds, not the window-manager frame // bounds (bug 581863). gdk_window_get_frame_extents would give the @@ -1797,7 +1797,7 @@ nsWindow::SetIcon(const nsAString& aIconSpec) } -LayoutDeviceIntPoint +nsIntPoint nsWindow::WidgetToScreenOffset() { gint x = 0, y = 0; @@ -2617,7 +2617,8 @@ nsWindow::OnMotionNotifyEvent(GdkEventMotion *aEvent) } else { LayoutDeviceIntPoint point(NSToIntFloor(aEvent->x_root), NSToIntFloor(aEvent->y_root)); - event.refPoint = point - WidgetToScreenOffset(); + event.refPoint = point - + LayoutDeviceIntPoint::FromUntyped(WidgetToScreenOffset()); } modifierState = aEvent->state; @@ -2695,7 +2696,8 @@ nsWindow::InitButtonEvent(WidgetMouseEvent& aEvent, } else { LayoutDeviceIntPoint point(NSToIntFloor(aGdkEvent->x_root), NSToIntFloor(aGdkEvent->y_root)); - aEvent.refPoint = point - WidgetToScreenOffset(); + aEvent.refPoint = point - + LayoutDeviceIntPoint::FromUntyped(WidgetToScreenOffset()); } guint modifierState = aGdkEvent->state; @@ -3207,7 +3209,8 @@ nsWindow::OnScrollEvent(GdkEventScroll *aEvent) // coordinates relative to this widget. LayoutDeviceIntPoint point(NSToIntFloor(aEvent->x_root), NSToIntFloor(aEvent->y_root)); - wheelEvent.refPoint = point - WidgetToScreenOffset(); + wheelEvent.refPoint = point - + LayoutDeviceIntPoint::FromUntyped(WidgetToScreenOffset()); } KeymapWrapper::InitInputEvent(wheelEvent, aEvent->state); @@ -6335,7 +6338,7 @@ nsWindow::GetDragInfo(WidgetMouseEvent* aMouseEvent, // moved since the mousedown. (On the other hand, it's quite likely // that the mouse has moved, which is why we use the mouse position // from the event.) - LayoutDeviceIntPoint offset = aMouseEvent->widget->WidgetToScreenOffset(); + nsIntPoint offset = aMouseEvent->widget->WidgetToScreenOffset(); *aRootX = aMouseEvent->refPoint.x + offset.x; *aRootY = aMouseEvent->refPoint.y + offset.y; @@ -6496,11 +6499,11 @@ nsWindow::GdkCoordToDevicePixels(gint coord) { return coord * GdkScaleFactor(); } -LayoutDeviceIntPoint +nsIntPoint nsWindow::GdkPointToDevicePixels(GdkPoint point) { gint scale = GdkScaleFactor(); - return LayoutDeviceIntPoint(point.x * scale, - point.y * scale); + return nsIntPoint(point.x * scale, + point.y * scale); } nsIntRect diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index 456e2bf2a39e..f86650366278 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -138,7 +138,7 @@ public: NS_IMETHOD SetTitle(const nsAString& aTitle) MOZ_OVERRIDE; NS_IMETHOD SetIcon(const nsAString& aIconSpec) MOZ_OVERRIDE; NS_IMETHOD SetWindowClass(const nsAString& xulWinType) MOZ_OVERRIDE; - virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; + virtual nsIntPoint WidgetToScreenOffset() MOZ_OVERRIDE; NS_IMETHOD EnableDragDrop(bool aEnable) MOZ_OVERRIDE; NS_IMETHOD CaptureMouse(bool aCapture) MOZ_OVERRIDE; NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 2983a6158bb9..ee76fed042fa 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -1668,16 +1668,12 @@ class nsIWidget : public nsISupports { NS_IMETHOD SetIcon(const nsAString& anIconSpec) = 0; /** - * Return this widget's origin in screen coordinates. The untyped version - * exists temporarily to ease conversion to typed coordinates. + * Return this widget's origin in screen coordinates. * * @return screen coordinates stored in the x,y members */ - virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() = 0; - virtual nsIntPoint WidgetToScreenOffsetUntyped() { - return mozilla::LayoutDeviceIntPoint::ToUntyped(WidgetToScreenOffset()); - } + virtual nsIntPoint WidgetToScreenOffset() = 0; /** * Given the specified client size, return the corresponding window size, diff --git a/widget/qt/nsWindow.cpp b/widget/qt/nsWindow.cpp index 680356b530b0..193d39e22bef 100644 --- a/widget/qt/nsWindow.cpp +++ b/widget/qt/nsWindow.cpp @@ -626,7 +626,7 @@ nsWindow::Invalidate(const nsIntRect &aRect) return NS_OK; } -LayoutDeviceIntPoint +nsIntPoint nsWindow::WidgetToScreenOffset() { NS_ENSURE_TRUE(mWidget, nsIntPoint(0,0)); @@ -634,7 +634,7 @@ nsWindow::WidgetToScreenOffset() QPoint origin(0, 0); origin = mWidget->mapToGlobal(origin); - return LayoutDeviceIntPoint(origin.x(), origin.y()); + return nsIntPoint(origin.x(), origin.y()); } void* diff --git a/widget/qt/nsWindow.h b/widget/qt/nsWindow.h index bf970a091205..70db05e60870 100644 --- a/widget/qt/nsWindow.h +++ b/widget/qt/nsWindow.h @@ -124,7 +124,7 @@ public: { return NS_OK; } - virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); + virtual nsIntPoint WidgetToScreenOffset(); NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus); NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, diff --git a/widget/windows/nsIMM32Handler.cpp b/widget/windows/nsIMM32Handler.cpp index 21834da35ba4..6aaae7bc45a7 100644 --- a/widget/windows/nsIMM32Handler.cpp +++ b/widget/windows/nsIMM32Handler.cpp @@ -1957,7 +1957,7 @@ nsIMM32Handler::SetIMERelatedWindowsPosOnPlugin(nsWindow* aWindow, // window needs to be specified the position in the client area. nsWindow* toplevelWindow = aWindow->GetTopLevelWindow(false); nsIntRect pluginRectInScreen = - editorRectEvent.mReply.mRect + toplevelWindow->WidgetToScreenOffsetUntyped(); + editorRectEvent.mReply.mRect + toplevelWindow->WidgetToScreenOffset(); nsIntRect winRectInScreen; aWindow->GetClientBounds(winRectInScreen); // composition window cannot be positioned on the edge of client area. @@ -1974,7 +1974,7 @@ nsIMM32Handler::SetIMERelatedWindowsPosOnPlugin(nsWindow* aWindow, int32_t yMost = std::min(pluginRectInScreen.YMost(), winRectInScreen.YMost()); clippedPluginRect.width = std::max(0, xMost - clippedPluginRect.x); clippedPluginRect.height = std::max(0, yMost - clippedPluginRect.y); - clippedPluginRect -= aWindow->WidgetToScreenOffsetUntyped(); + clippedPluginRect -= aWindow->WidgetToScreenOffset(); // Cover the plugin with native caret. This prevents IME's window and plugin // overlap. @@ -2013,10 +2013,10 @@ nsIMM32Handler::ResolveIMECaretPos(nsIWidget* aReferenceWidget, return; if (aReferenceWidget) - aOutRect.MoveBy(aReferenceWidget->WidgetToScreenOffsetUntyped()); + aOutRect.MoveBy(aReferenceWidget->WidgetToScreenOffset()); if (aNewOriginWidget) - aOutRect.MoveBy(-aNewOriginWidget->WidgetToScreenOffsetUntyped()); + aOutRect.MoveBy(-aNewOriginWidget->WidgetToScreenOffset()); } /* static */ nsresult diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index ae7d53a8b0fb..8156c4248d47 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -3198,7 +3198,7 @@ nsTextStore::GetTextExt(TsViewCookie vcView, return E_FAIL; } - event.mReply.mRect.MoveBy(refWindow->WidgetToScreenOffsetUntyped()); + event.mReply.mRect.MoveBy(refWindow->WidgetToScreenOffset()); } // get bounding screen rect to test for clipping @@ -3336,7 +3336,7 @@ nsTextStore::GetScreenExtInternal(RECT &aScreenExt) // Clip frame rect to window rect boundRect.IntersectRect(event.mReply.mRect, boundRect); if (!boundRect.IsEmpty()) { - boundRect.MoveBy(refWindow->WidgetToScreenOffsetUntyped()); + boundRect.MoveBy(refWindow->WidgetToScreenOffset()); ::SetRect(&aScreenExt, boundRect.x, boundRect.y, boundRect.XMost(), boundRect.YMost()); } else { @@ -4325,8 +4325,8 @@ nsTextStore::CreateNativeCaret() } if (toplevelWindow != window) { - caretRect.MoveBy(toplevelWindow->WidgetToScreenOffsetUntyped()); - caretRect.MoveBy(-window->WidgetToScreenOffsetUntyped()); + caretRect.MoveBy(toplevelWindow->WidgetToScreenOffset()); + caretRect.MoveBy(-window->WidgetToScreenOffset()); } ::SetCaretPos(caretRect.x, caretRect.y); diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 46340afd430a..5bd07ff155e4 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -1991,7 +1991,7 @@ nsIntPoint nsWindow::GetClientOffset() RECT r1; GetWindowRect(mWnd, &r1); - LayoutDeviceIntPoint pt = WidgetToScreenOffset(); + nsIntPoint pt = WidgetToScreenOffset(); return nsIntPoint(pt.x - r1.left, pt.y - r1.top); } @@ -3061,13 +3061,13 @@ NS_METHOD nsWindow::SetIcon(const nsAString& aIconSpec) * **************************************************************/ -LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() +nsIntPoint nsWindow::WidgetToScreenOffset() { POINT point; point.x = 0; point.y = 0; ::ClientToScreen(mWnd, &point); - return LayoutDeviceIntPoint(point.x, point.y); + return nsIntPoint(point.x, point.y); } nsIntSize nsWindow::ClientToWindowSize(const nsIntSize& aClientSize) @@ -3819,7 +3819,7 @@ bool nsWindow::DispatchMouseEvent(uint32_t aEventType, WPARAM wParam, aInputSource == nsIDOMMouseEvent::MOZ_SOURCE_PEN || !(WinUtils::GetIsMouseFromTouch(aEventType) && mTouchWindow); - nsIntPoint mpScreen = eventPoint + WidgetToScreenOffsetUntyped(); + nsIntPoint mpScreen = eventPoint + WidgetToScreenOffset(); // Suppress mouse moves caused by widget creation if (aEventType == NS_MOUSE_MOVE) diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index d76931dd8240..e580254debe0 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -136,7 +136,7 @@ public: virtual void FreeNativeData(void * data, uint32_t aDataType); NS_IMETHOD SetTitle(const nsAString& aTitle); NS_IMETHOD SetIcon(const nsAString& aIconSpec); - virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); + virtual nsIntPoint WidgetToScreenOffset(); virtual nsIntSize ClientToWindowSize(const nsIntSize& aClientSize); NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsEventStatus& aStatus); diff --git a/widget/windows/winrt/MetroWidget.cpp b/widget/windows/winrt/MetroWidget.cpp index a194f1286632..2c4ad6e06035 100644 --- a/widget/windows/winrt/MetroWidget.cpp +++ b/widget/windows/winrt/MetroWidget.cpp @@ -1492,10 +1492,10 @@ MetroWidget::SetTitle(const nsAString& aTitle) return NS_OK; } -LayoutDeviceIntPoint +nsIntPoint MetroWidget::WidgetToScreenOffset() { - return LayoutDeviceIntPoint(0,0); + return nsIntPoint(0,0); } NS_IMETHODIMP diff --git a/widget/windows/winrt/MetroWidget.h b/widget/windows/winrt/MetroWidget.h index bd6c2d465663..74742d98705a 100644 --- a/widget/windows/winrt/MetroWidget.h +++ b/widget/windows/winrt/MetroWidget.h @@ -172,7 +172,7 @@ public: virtual nsresult ConfigureChildren(const nsTArray& aConfigurations); virtual void* GetNativeData(uint32_t aDataType); virtual void FreeNativeData(void * data, uint32_t aDataType); - virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); + virtual nsIntPoint WidgetToScreenOffset(); already_AddRefed GetPresShell(); From 5a8a76484be7583836bf47d672db814caa8ee5ca Mon Sep 17 00:00:00 2001 From: Chris Pearce Date: Mon, 2 Feb 2015 13:48:36 +1300 Subject: [PATCH 08/16] Bug 1123498 - Test for MP4Reader's demuxer skip-to-next-keyframe. r=mattwoodrow --- dom/media/gtest/MockMediaResource.cpp | 3 ++- dom/media/gtest/TestMP4Demuxer.cpp | 31 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/dom/media/gtest/MockMediaResource.cpp b/dom/media/gtest/MockMediaResource.cpp index b8b1ebaf92c5..03cc0e5e2738 100644 --- a/dom/media/gtest/MockMediaResource.cpp +++ b/dom/media/gtest/MockMediaResource.cpp @@ -60,7 +60,8 @@ MockMediaResource::ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, int64_t MockMediaResource::GetLength() { - return fseek(mFileHandle, 0, SEEK_END); + fseek(mFileHandle, 0, SEEK_END); + return ftell(mFileHandle); } void diff --git a/dom/media/gtest/TestMP4Demuxer.cpp b/dom/media/gtest/TestMP4Demuxer.cpp index 9559eb6a6701..0aee4190cd18 100644 --- a/dom/media/gtest/TestMP4Demuxer.cpp +++ b/dom/media/gtest/TestMP4Demuxer.cpp @@ -331,3 +331,34 @@ TEST(MP4Demuxer, CENCFrag) } EXPECT_EQ(ArrayLength(audio), i); } + +TEST(MP4Demuxer, GetNextKeyframe) +{ + nsRefPtr b = new MP4DemuxerBinding("gizmo-frag.mp4"); + MonitorAutoLock mon(b->mMonitor); + MP4Demuxer* d = b->demuxer; + + EXPECT_TRUE(d->Init()); + + // Insert a [0,end] buffered range, to simulate Moof's being buffered + // via MSE. + auto len = b->resource->GetLength(); + b->resource->MockAddBufferedRange(0, len); + + // Rebuild the index so that it can be used to find the keyframes. + nsTArray ranges; + EXPECT_TRUE(NS_SUCCEEDED(b->resource->GetCachedRanges(ranges))); + d->UpdateIndex(ranges); + + // gizmp-frag has two keyframes; one at dts=cts=0, and another at + // dts=cts=1000000. Verify we get expected results. + + MP4Sample* sample; + size_t i = 0; + const int64_t keyframe = 1000000; + while (!!(sample = d->DemuxVideoSample())) { + int64_t expected = (sample->decode_timestamp < keyframe) ? keyframe : -1; + EXPECT_EQ(d->GetNextKeyframeTime(), expected); + i++; + } +} From a35dbaeebfcdaf2cc59d447163be39ce05f5df84 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Wed, 28 Jan 2015 18:00:40 +0900 Subject: [PATCH 09/16] Bug 1126593 - Add a global fallible instance, so that using fallible works directly, everywhere. r=njn --HG-- rename : memory/mozalloc/fallible.h => memory/fallible/fallible.h --- build/gecko_templates.mozbuild | 5 + dom/base/DOMParser.cpp | 2 +- dom/base/FragmentOrElement.cpp | 2 +- dom/base/URLSearchParams.cpp | 2 +- dom/base/nsContentUtils.cpp | 20 ++-- dom/base/nsDOMFileReader.cpp | 4 +- dom/base/nsDocumentEncoder.cpp | 2 +- dom/base/nsGenericDOMDataNode.cpp | 5 +- dom/base/nsJSEnvironment.cpp | 1 - dom/base/nsJSUtils.h | 2 +- dom/base/nsScriptNameSpaceManager.cpp | 4 +- dom/base/nsTextFragment.h | 16 +-- dom/base/nsXMLHttpRequest.cpp | 2 +- dom/bindings/MozMap.h | 4 +- dom/canvas/WebGLContext.cpp | 1 - dom/canvas/WebGLContextDraw.cpp | 2 +- dom/canvas/WebGLContextGL.cpp | 7 +- dom/encoding/TextDecoder.cpp | 1 - dom/encoding/TextEncoder.cpp | 1 - dom/fetch/Fetch.cpp | 4 +- dom/filehandle/MemoryStreams.cpp | 2 +- dom/html/HTMLFrameSetElement.cpp | 1 - dom/html/nsTextEditorState.cpp | 2 - dom/indexedDB/ActorsParent.cpp | 2 - dom/indexedDB/IDBObjectStore.cpp | 2 +- dom/media/fmp4/MP4Stream.h | 3 +- dom/media/webaudio/AudioDestinationNode.cpp | 3 +- dom/media/webaudio/MediaBufferDecoder.cpp | 3 +- dom/plugins/base/nsPluginTags.cpp | 2 +- dom/storage/DOMStorage.cpp | 2 +- dom/svg/SVGContentUtils.h | 4 +- dom/svg/SVGFEConvolveMatrixElement.cpp | 1 - dom/xslt/base/txDouble.cpp | 2 +- dom/xslt/xpath/txMozillaXPathTreeWalker.cpp | 2 +- editor/libeditor/nsTextEditRules.cpp | 2 +- .../spellcheck/src/mozInlineSpellWordUtil.cpp | 2 +- gfx/layers/client/TextureClient.cpp | 3 +- gfx/thebes/gfxFT2FontList.cpp | 1 - image/decoders/icon/win/nsIconChannel.cpp | 2 +- image/encoders/bmp/nsBMPEncoder.cpp | 1 - image/src/SourceBuffer.h | 1 - intl/uconv/nsScriptableUConv.cpp | 6 +- layout/base/nsBidiPresUtils.cpp | 2 +- .../src/mediapipeline/MediaPipeline.cpp | 1 - .../fallible.h => fallible/fallible.cpp} | 9 +- memory/fallible/fallible.h | 67 +++++++++++ memory/fallible/moz.build | 30 +++++ memory/mozalloc/moz.build | 1 - modules/libjar/nsZipArchive.cpp | 2 +- modules/libpref/nsPrefBranch.cpp | 2 +- modules/libpref/prefapi.cpp | 2 +- moz.build | 1 + netwerk/base/nsBufferedStreams.cpp | 3 +- netwerk/base/nsNetUtil.h | 2 +- netwerk/base/nsStandardURL.cpp | 2 +- netwerk/base/nsUnicharStreamLoader.cpp | 4 +- netwerk/cache/nsCacheEntry.cpp | 2 +- netwerk/cache/nsDiskCacheDeviceSQL.cpp | 2 +- netwerk/protocol/http/nsHttp.cpp | 2 +- .../protocol/websocket/WebSocketChannel.cpp | 4 +- .../converters/nsDirIndexParser.cpp | 2 +- parser/html/nsHtml5OwningUTF16Buffer.cpp | 5 +- parser/html/nsHtml5StreamParser.cpp | 6 +- parser/htmlparser/nsHTMLEntities.cpp | 4 +- parser/htmlparser/nsScannerString.cpp | 4 +- security/manager/ssl/src/nsCertTree.cpp | 2 +- services/crypto/component/nsSyncJPAKE.cpp | 6 +- toolkit/components/downloads/SQLFunctions.cpp | 2 +- toolkit/components/places/Helpers.cpp | 2 +- toolkit/components/telemetry/Telemetry.cpp | 2 +- widget/windows/nsIMM32Handler.cpp | 4 +- xpcom/base/nsCycleCollector.cpp | 2 +- xpcom/ds/nsStaticNameTable.cpp | 2 +- xpcom/ds/nsSupportsPrimitives.cpp | 6 +- xpcom/glue/moz.build | 5 + xpcom/glue/nomozalloc/moz.build | 5 + xpcom/glue/nsBaseHashtable.h | 2 +- xpcom/glue/nsDeque.h | 4 +- xpcom/glue/nsRefPtrHashtable.h | 2 +- xpcom/glue/nsTHashtable.h | 2 +- xpcom/glue/pldhash.cpp | 4 +- xpcom/glue/standalone/moz.build | 5 + xpcom/glue/standalone/staticruntime/moz.build | 5 + xpcom/glue/staticruntime/moz.build | 5 + xpcom/io/Base64.cpp | 4 +- xpcom/io/SnappyCompressOutputStream.cpp | 4 +- xpcom/io/SnappyUncompressInputStream.cpp | 4 +- xpcom/io/nsBinaryStream.cpp | 2 +- xpcom/io/nsLocalFileWin.cpp | 2 +- xpcom/io/nsNativeCharsetUtils.cpp | 6 +- xpcom/string/nsAString.h | 2 - xpcom/string/nsReadableUtils.cpp | 24 ++-- xpcom/string/nsTStringObsolete.cpp | 6 +- xpcom/string/nsTSubstring.cpp | 42 +++---- xpcom/string/nsTSubstring.h | 43 +++---- xpcom/tests/TestPLDHash.cpp | 6 +- xpcom/tests/gtest/TestStrings.cpp | 113 +++++++++--------- 97 files changed, 358 insertions(+), 262 deletions(-) rename memory/{mozalloc/fallible.h => fallible/fallible.cpp} (63%) create mode 100644 memory/fallible/fallible.h create mode 100644 memory/fallible/moz.build diff --git a/build/gecko_templates.mozbuild b/build/gecko_templates.mozbuild index 9d07947ce412..46ff7d2b456f 100644 --- a/build/gecko_templates.mozbuild +++ b/build/gecko_templates.mozbuild @@ -78,6 +78,11 @@ def GeckoBinary(linkage='dependent', msvcrt='dynamic', mozglue=None): else: error('`mozglue` must be "program" or "library"') + if not CONFIG['JS_STANDALONE']: + USE_LIBS += [ + 'fallible', + ] + @template def GeckoProgram(name, linkage='standalone', **kwargs): diff --git a/dom/base/DOMParser.cpp b/dom/base/DOMParser.cpp index b9bec3e69b6e..6d5e06f8851b 100644 --- a/dom/base/DOMParser.cpp +++ b/dom/base/DOMParser.cpp @@ -109,7 +109,7 @@ DOMParser::ParseFromString(const nsAString& str, nsAutoCString utf8str; // Convert from UTF16 to UTF8 using fallible allocations - if (!AppendUTF16toUTF8(str, utf8str, mozilla::fallible_t())) { + if (!AppendUTF16toUTF8(str, utf8str, mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp index de0734441086..f29289c81e19 100644 --- a/dom/base/FragmentOrElement.cpp +++ b/dom/base/FragmentOrElement.cpp @@ -2202,7 +2202,7 @@ public: bool ToString(nsAString& aOut) { - if (!aOut.SetCapacity(mLength, fallible_t())) { + if (!aOut.SetCapacity(mLength, fallible)) { return false; } diff --git a/dom/base/URLSearchParams.cpp b/dom/base/URLSearchParams.cpp index 0b9cd4cf03c0..c2d5a89f54f9 100644 --- a/dom/base/URLSearchParams.cpp +++ b/dom/base/URLSearchParams.cpp @@ -190,7 +190,7 @@ URLSearchParams::ConvertString(const nsACString& aInput, nsAString& aOutput) return; } - if (!aOutput.SetLength(outputLength, fallible_t())) { + if (!aOutput.SetLength(outputLength, fallible)) { return; } diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index b84e3c655d0c..63dacabbb110 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -732,7 +732,7 @@ nsContentUtils::Atob(const nsAString& aAsciiBase64String, const char16_t* start = aAsciiBase64String.BeginReading(); const char16_t* end = aAsciiBase64String.EndReading(); nsString trimmedString; - if (!trimmedString.SetCapacity(aAsciiBase64String.Length(), fallible_t())) { + if (!trimmedString.SetCapacity(aAsciiBase64String.Length(), fallible)) { return NS_ERROR_DOM_INVALID_CHARACTER_ERR; } while (start < end) { @@ -4425,20 +4425,20 @@ nsContentUtils::SetNodeTextContent(nsIContent* aContent, static bool AppendNodeTextContentsRecurse(nsINode* aNode, nsAString& aResult, - const mozilla::fallible_t&) + const fallible_t& aFallible) { for (nsIContent* child = aNode->GetFirstChild(); child; child = child->GetNextSibling()) { if (child->IsElement()) { bool ok = AppendNodeTextContentsRecurse(child, aResult, - mozilla::fallible_t()); + aFallible); if (!ok) { return false; } } else if (child->IsNodeOfType(nsINode::eTEXT)) { - bool ok = child->AppendTextTo(aResult, mozilla::fallible_t()); + bool ok = child->AppendTextTo(aResult, aFallible); if (!ok) { return false; } @@ -4452,21 +4452,21 @@ AppendNodeTextContentsRecurse(nsINode* aNode, nsAString& aResult, bool nsContentUtils::AppendNodeTextContent(nsINode* aNode, bool aDeep, nsAString& aResult, - const mozilla::fallible_t&) + const fallible_t& aFallible) { if (aNode->IsNodeOfType(nsINode::eTEXT)) { return static_cast(aNode)->AppendTextTo(aResult, - mozilla::fallible_t()); + aFallible); } else if (aDeep) { - return AppendNodeTextContentsRecurse(aNode, aResult, mozilla::fallible_t()); + return AppendNodeTextContentsRecurse(aNode, aResult, aFallible); } else { for (nsIContent* child = aNode->GetFirstChild(); child; child = child->GetNextSibling()) { if (child->IsNodeOfType(nsINode::eTEXT)) { - bool ok = child->AppendTextTo(aResult, mozilla::fallible_t()); + bool ok = child->AppendTextTo(aResult, fallible); if (!ok) { return false; } @@ -6242,7 +6242,7 @@ void nsContentUtils::RemoveNewlines(nsString &aString) void nsContentUtils::PlatformToDOMLineBreaks(nsString &aString) { - if (!PlatformToDOMLineBreaks(aString, mozilla::fallible_t())) { + if (!PlatformToDOMLineBreaks(aString, fallible)) { aString.AllocFailed(aString.Length()); } } @@ -6962,7 +6962,7 @@ bool nsContentUtils::GetNodeTextContent(nsINode* aNode, bool aDeep, nsAString& aResult) { aResult.Truncate(); - return AppendNodeTextContent(aNode, aDeep, aResult, mozilla::fallible_t()); + return AppendNodeTextContent(aNode, aDeep, aResult, fallible); } void diff --git a/dom/base/nsDOMFileReader.cpp b/dom/base/nsDOMFileReader.cpp index fbeac9e9885e..6267e0e985db 100644 --- a/dom/base/nsDOMFileReader.cpp +++ b/dom/base/nsDOMFileReader.cpp @@ -348,7 +348,7 @@ nsDOMFileReader::DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount) if (uint64_t(oldLen) + aCount > UINT32_MAX) return NS_ERROR_OUT_OF_MEMORY; char16_t *buf = nullptr; - mResult.GetMutableData(&buf, oldLen + aCount, fallible_t()); + mResult.GetMutableData(&buf, oldLen + aCount, fallible); NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY); uint32_t bytesRead = 0; @@ -522,7 +522,7 @@ nsDOMFileReader::GetAsDataURL(nsIDOMBlob *aFile, rv = Base64Encode(Substring(aFileData, aDataLen), encodedData); NS_ENSURE_SUCCESS(rv, rv); - if (!AppendASCIItoUTF16(encodedData, aResult, fallible_t())) { + if (!AppendASCIItoUTF16(encodedData, aResult, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/base/nsDocumentEncoder.cpp b/dom/base/nsDocumentEncoder.cpp index 44b3df677760..152add2180ad 100644 --- a/dom/base/nsDocumentEncoder.cpp +++ b/dom/base/nsDocumentEncoder.cpp @@ -572,7 +572,7 @@ ConvertAndWrite(const nsAString& aString, } nsAutoCString charXferString; - if (!charXferString.SetLength(charLength, fallible_t())) + if (!charXferString.SetLength(charLength, fallible)) return NS_ERROR_OUT_OF_MEMORY; char* charXferBuf = charXferString.BeginWriting(); diff --git a/dom/base/nsGenericDOMDataNode.cpp b/dom/base/nsGenericDOMDataNode.cpp index 81a28839c3eb..d4057ecbc5a1 100644 --- a/dom/base/nsGenericDOMDataNode.cpp +++ b/dom/base/nsGenericDOMDataNode.cpp @@ -1074,9 +1074,10 @@ nsGenericDOMDataNode::AppendTextTo(nsAString& aResult) } bool -nsGenericDOMDataNode::AppendTextTo(nsAString& aResult, const mozilla::fallible_t&) +nsGenericDOMDataNode::AppendTextTo(nsAString& aResult, + const mozilla::fallible_t& aFallible) { - return mText.AppendTo(aResult, mozilla::fallible_t()); + return mText.AppendTo(aResult, aFallible); } already_AddRefed diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 7c1ca0c7dd56..7043ffd4bae3 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -2773,7 +2773,6 @@ nsJSArgArray::nsJSArgArray(JSContext *aContext, uint32_t argc, JS::Value *argv, // copy the array - we don't know its lifetime, and ours is tied to xpcom // refcounting. if (argc) { - static const fallible_t fallible = fallible_t(); mArgv = new (fallible) JS::Heap[argc]; if (!mArgv) { *prv = NS_ERROR_OUT_OF_MEMORY; diff --git a/dom/base/nsJSUtils.h b/dom/base/nsJSUtils.h index d696698d8c6b..82d3488a420a 100644 --- a/dom/base/nsJSUtils.h +++ b/dom/base/nsJSUtils.h @@ -161,7 +161,7 @@ AssignJSString(JSContext *cx, T &dest, JSString *s) size_t len = js::GetStringLength(s); static_assert(js::MaxStringLength < (1 << 28), "Shouldn't overflow here or in SetCapacity"); - if (MOZ_UNLIKELY(!dest.SetLength(len, mozilla::fallible_t()))) { + if (MOZ_UNLIKELY(!dest.SetLength(len, mozilla::fallible))) { JS_ReportOutOfMemory(cx); return false; } diff --git a/dom/base/nsScriptNameSpaceManager.cpp b/dom/base/nsScriptNameSpaceManager.cpp index b5e10aa8a14f..d4b935fda173 100644 --- a/dom/base/nsScriptNameSpaceManager.cpp +++ b/dom/base/nsScriptNameSpaceManager.cpp @@ -328,13 +328,13 @@ nsScriptNameSpaceManager::Init() mIsInitialized = PL_DHashTableInit(&mGlobalNames, &hash_table_ops, sizeof(GlobalNameMapEntry), - fallible_t(), + fallible, GLOBALNAME_HASHTABLE_INITIAL_LENGTH); NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_OUT_OF_MEMORY); mIsInitialized = PL_DHashTableInit(&mNavigatorNames, &hash_table_ops, sizeof(GlobalNameMapEntry), - fallible_t(), + fallible, GLOBALNAME_HASHTABLE_INITIAL_LENGTH); if (!mIsInitialized) { PL_DHashTableFinish(&mGlobalNames); diff --git a/dom/base/nsTextFragment.h b/dom/base/nsTextFragment.h index c7c587dc807d..84597dd1862b 100644 --- a/dom/base/nsTextFragment.h +++ b/dom/base/nsTextFragment.h @@ -125,7 +125,7 @@ public: * Append the contents of this string fragment to aString */ void AppendTo(nsAString& aString) const { - if (!AppendTo(aString, mozilla::fallible_t())) { + if (!AppendTo(aString, mozilla::fallible)) { aString.AllocFailed(aString.Length() + GetLength()); } } @@ -135,9 +135,9 @@ public: * @return false if an out of memory condition is detected, true otherwise */ bool AppendTo(nsAString& aString, - const mozilla::fallible_t&) const NS_WARN_UNUSED_RESULT { + const mozilla::fallible_t& aFallible) const NS_WARN_UNUSED_RESULT { if (mState.mIs2b) { - bool ok = aString.Append(m2b, mState.mLength, mozilla::fallible_t()); + bool ok = aString.Append(m2b, mState.mLength, aFallible); if (!ok) { return false; } @@ -145,7 +145,7 @@ public: return true; } else { return AppendASCIItoUTF16(Substring(m1b, mState.mLength), aString, - mozilla::fallible_t()); + aFallible); } } @@ -155,7 +155,7 @@ public: * @param aLength the length of the substring */ void AppendTo(nsAString& aString, int32_t aOffset, int32_t aLength) const { - if (!AppendTo(aString, aOffset, aLength, mozilla::fallible_t())) { + if (!AppendTo(aString, aOffset, aLength, mozilla::fallible)) { aString.AllocFailed(aString.Length() + aLength); } } @@ -168,10 +168,10 @@ public: * @return false if an out of memory condition is detected, true otherwise */ bool AppendTo(nsAString& aString, int32_t aOffset, int32_t aLength, - const mozilla::fallible_t&) const NS_WARN_UNUSED_RESULT + const mozilla::fallible_t& aFallible) const NS_WARN_UNUSED_RESULT { if (mState.mIs2b) { - bool ok = aString.Append(m2b + aOffset, aLength, mozilla::fallible_t()); + bool ok = aString.Append(m2b + aOffset, aLength, aFallible); if (!ok) { return false; } @@ -179,7 +179,7 @@ public: return true; } else { return AppendASCIItoUTF16(Substring(m1b + aOffset, aLength), aString, - mozilla::fallible_t()); + aFallible); } } diff --git a/dom/base/nsXMLHttpRequest.cpp b/dom/base/nsXMLHttpRequest.cpp index b4cf06041228..8f0aa506b2ec 100644 --- a/dom/base/nsXMLHttpRequest.cpp +++ b/dom/base/nsXMLHttpRequest.cpp @@ -670,7 +670,7 @@ nsXMLHttpRequest::AppendToResponseText(const char * aSrcBuffer, &destBufferLen); NS_ENSURE_SUCCESS(rv, rv); - if (!mResponseText.SetCapacity(mResponseText.Length() + destBufferLen, fallible_t())) { + if (!mResponseText.SetCapacity(mResponseText.Length() + destBufferLen, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/bindings/MozMap.h b/dom/bindings/MozMap.h index 22605aac1663..d303c664f37d 100644 --- a/dom/bindings/MozMap.h +++ b/dom/bindings/MozMap.h @@ -102,9 +102,7 @@ public: DataType* AddEntry(const nsAString& aKey) NS_WARN_UNUSED_RESULT { - // XXXbz can't just use fallible_t() because our superclass has a - // private typedef by that name. - EntryType* ent = this->PutEntry(aKey, mozilla::fallible_t()); + EntryType* ent = this->PutEntry(aKey, fallible); if (!ent) { return nullptr; } diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index 29c45bde703f..749621074af9 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -1060,7 +1060,6 @@ WebGLContext::GetImageBuffer(uint8_t** out_imageBuffer, int32_t* out_format) if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map)) return; - static const fallible_t fallible = fallible_t(); uint8_t* imageBuffer = new (fallible) uint8_t[mWidth * mHeight * 4]; if (!imageBuffer) { dataSurface->Unmap(); diff --git a/dom/canvas/WebGLContextDraw.cpp b/dom/canvas/WebGLContextDraw.cpp index 8ba46d457e76..2c725ae82ff6 100644 --- a/dom/canvas/WebGLContextDraw.cpp +++ b/dom/canvas/WebGLContextDraw.cpp @@ -581,7 +581,7 @@ WebGLContext::DoFakeVertexAttrib0(GLuint vertexCount) GetAndFlushUnderlyingGLErrors(); if (mFakeVertexAttrib0BufferStatus == WebGLVertexAttrib0Status::EmulatedInitializedArray) { - UniquePtr array(new ((fallible_t())) GLfloat[4 * vertexCount]); + UniquePtr array(new (fallible) GLfloat[4 * vertexCount]); if (!array) { ErrorOutOfMemory("Fake attrib0 array."); return false; diff --git a/dom/canvas/WebGLContextGL.cpp b/dom/canvas/WebGLContextGL.cpp index 532e5ce60a2f..999b71b67e42 100644 --- a/dom/canvas/WebGLContextGL.cpp +++ b/dom/canvas/WebGLContextGL.cpp @@ -48,7 +48,6 @@ #include "mozilla/dom/ImageData.h" #include "mozilla/dom/ToJSValue.h" #include "mozilla/Endian.h" -#include "mozilla/fallible.h" using namespace mozilla; using namespace mozilla::dom; @@ -2086,7 +2085,7 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, uint32_t subrect_byteLength = (subrect_height-1)*subrect_alignedRowSize + subrect_plainRowSize; // create subrect buffer, call glReadPixels, copy pixels into destination buffer, delete subrect buffer - UniquePtr subrect_data(new ((fallible_t())) GLubyte[subrect_byteLength]); + UniquePtr subrect_data(new (fallible) GLubyte[subrect_byteLength]); if (!subrect_data) return ErrorOutOfMemory("readPixels: subrect_data"); @@ -3203,7 +3202,7 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level, else { size_t convertedDataSize = height * dstStride; - convertedData = new ((fallible_t())) uint8_t[convertedDataSize]; + convertedData = new (fallible) uint8_t[convertedDataSize]; if (!convertedData) { ErrorOutOfMemory("texImage2D: Ran out of memory when allocating" " a buffer for doing format conversion."); @@ -3404,7 +3403,7 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level, if (!noConversion) { size_t convertedDataSize = height * dstStride; - convertedData = new ((fallible_t())) uint8_t[convertedDataSize]; + convertedData = new (fallible) uint8_t[convertedDataSize]; if (!convertedData) { ErrorOutOfMemory("texImage2D: Ran out of memory when allocating" " a buffer for doing format conversion."); diff --git a/dom/encoding/TextDecoder.cpp b/dom/encoding/TextDecoder.cpp index 963dcac1333d..25a5ea97d888 100644 --- a/dom/encoding/TextDecoder.cpp +++ b/dom/encoding/TextDecoder.cpp @@ -63,7 +63,6 @@ TextDecoder::Decode(const char* aInput, const int32_t aLength, } // Need a fallible allocator because the caller may be a content // and the content can specify the length of the string. - static const fallible_t fallible = fallible_t(); nsAutoArrayPtr buf(new (fallible) char16_t[outLen + 1]); if (!buf) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); diff --git a/dom/encoding/TextEncoder.cpp b/dom/encoding/TextEncoder.cpp index 023f9b16c852..ae7ff4b7706e 100644 --- a/dom/encoding/TextEncoder.cpp +++ b/dom/encoding/TextEncoder.cpp @@ -53,7 +53,6 @@ TextEncoder::Encode(JSContext* aCx, } // Need a fallible allocator because the caller may be a content // and the content can specify the length of the string. - static const fallible_t fallible = fallible_t(); nsAutoArrayPtr buf(new (fallible) char[maxLen + 1]); if (!buf) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp index 44cecf0fd810..9abbd7824c3e 100644 --- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -470,7 +470,7 @@ ExtractFromUSVString(const nsString& aStr, } nsCString encoded; - if (!encoded.SetCapacity(destBufferLen, fallible_t())) { + if (!encoded.SetCapacity(destBufferLen, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -583,7 +583,7 @@ public: return rv; } - if (!mDecoded.SetCapacity(mDecoded.Length() + destBufferLen, fallible_t())) { + if (!mDecoded.SetCapacity(mDecoded.Length() + destBufferLen, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/filehandle/MemoryStreams.cpp b/dom/filehandle/MemoryStreams.cpp index 67400631159b..13d8001beac6 100644 --- a/dom/filehandle/MemoryStreams.cpp +++ b/dom/filehandle/MemoryStreams.cpp @@ -26,7 +26,7 @@ MemoryOutputStream::Create(uint64_t aSize) nsRefPtr stream = new MemoryOutputStream(); char* dummy; - uint32_t length = stream->mData.GetMutableData(&dummy, aSize, fallible_t()); + uint32_t length = stream->mData.GetMutableData(&dummy, aSize, fallible); NS_ENSURE_TRUE(length == aSize, nullptr); return stream.forget(); diff --git a/dom/html/HTMLFrameSetElement.cpp b/dom/html/HTMLFrameSetElement.cpp index a292f061f555..76ae4a9027eb 100644 --- a/dom/html/HTMLFrameSetElement.cpp +++ b/dom/html/HTMLFrameSetElement.cpp @@ -232,7 +232,6 @@ HTMLFrameSetElement::ParseRowCol(const nsAString & aValue, commaX = spec.FindChar(sComma, commaX + 1); } - static const fallible_t fallible = fallible_t(); nsFramesetSpec* specs = new (fallible) nsFramesetSpec[count]; if (!specs) { *aSpecs = nullptr; diff --git a/dom/html/nsTextEditorState.cpp b/dom/html/nsTextEditorState.cpp index 92f748c46b83..68ff1a25d042 100644 --- a/dom/html/nsTextEditorState.cpp +++ b/dom/html/nsTextEditorState.cpp @@ -1873,8 +1873,6 @@ bool nsTextEditorState::SetValue(const nsAString& aValue, bool aUserInput, bool aSetValueChanged) { - mozilla::fallible_t fallible; - if (mEditor && mBoundFrame) { // The InsertText call below might flush pending notifications, which // could lead into a scheduled PrepareEditor to be called. That will diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 5e41ba09b530..690e8f61de2c 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -146,8 +146,6 @@ const int32_t kStorageProgressGranularity = 1000; const char kSavepointClause[] = "SAVEPOINT sp;"; -const fallible_t fallible = fallible_t(); - const uint32_t kFileCopyBufferSize = 32768; const char kJournalDirectoryName[] = "journals"; diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index d3f89fff6496..db4014cb217f 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -464,7 +464,7 @@ StructuredCloneReadString(JSStructuredCloneReader* aReader, } length = NativeEndian::swapFromLittleEndian(length); - if (!aString.SetLength(length, fallible_t())) { + if (!aString.SetLength(length, fallible)) { NS_WARNING("Out of memory?"); return false; } diff --git a/dom/media/fmp4/MP4Stream.h b/dom/media/fmp4/MP4Stream.h index 912d4f00fe90..f45989e5fe4f 100644 --- a/dom/media/fmp4/MP4Stream.h +++ b/dom/media/fmp4/MP4Stream.h @@ -11,7 +11,6 @@ #include "MediaResource.h" -#include "mozilla/fallible.h" #include "mozilla/Maybe.h" #include "mozilla/Monitor.h" @@ -77,7 +76,7 @@ private: bool Init() { - mBuffer = new ((fallible_t())) char[mCount]; + mBuffer = new (fallible) char[mCount]; return !!mBuffer; } diff --git a/dom/media/webaudio/AudioDestinationNode.cpp b/dom/media/webaudio/AudioDestinationNode.cpp index c0dd1d31f74c..4d4766147379 100644 --- a/dom/media/webaudio/AudioDestinationNode.cpp +++ b/dom/media/webaudio/AudioDestinationNode.cpp @@ -62,9 +62,8 @@ public: // channels or size, but it's OK since we'll deal with the failure // gracefully. if (mInputChannels.SetLength(mNumberOfChannels)) { - static const fallible_t fallible = fallible_t(); for (uint32_t i = 0; i < mNumberOfChannels; ++i) { - mInputChannels[i] = new(fallible) float[mLength]; + mInputChannels[i] = new (fallible) float[mLength]; if (!mInputChannels[i]) { mInputChannels.Clear(); break; diff --git a/dom/media/webaudio/MediaBufferDecoder.cpp b/dom/media/webaudio/MediaBufferDecoder.cpp index 938d4089f048..e4fb265f422d 100644 --- a/dom/media/webaudio/MediaBufferDecoder.cpp +++ b/dom/media/webaudio/MediaBufferDecoder.cpp @@ -333,13 +333,12 @@ MediaDecodeTask::FinishDecode() // Allocate the channel buffers. Note that if we end up resampling, we may // write fewer bytes than mResampledFrames to the output buffer, in which // case mWriteIndex will tell us how many valid samples we have. - static const fallible_t fallible = fallible_t(); bool memoryAllocationSuccess = true; if (!mDecodeJob.mChannelBuffers.SetLength(channelCount)) { memoryAllocationSuccess = false; } else { for (uint32_t i = 0; i < channelCount; ++i) { - mDecodeJob.mChannelBuffers[i] = new(fallible) float[resampledFrames]; + mDecodeJob.mChannelBuffers[i] = new (fallible) float[resampledFrames]; if (!mDecodeJob.mChannelBuffers[i]) { memoryAllocationSuccess = false; break; diff --git a/dom/plugins/base/nsPluginTags.cpp b/dom/plugins/base/nsPluginTags.cpp index a89f1e4009f3..d93c05e4f22d 100644 --- a/dom/plugins/base/nsPluginTags.cpp +++ b/dom/plugins/base/nsPluginTags.cpp @@ -259,7 +259,7 @@ static nsresult ConvertToUTF8(nsIUnicodeDecoder *aUnicodeDecoder, nsresult rv = aUnicodeDecoder->GetMaxLength(aString.get(), numberOfBytes, &outUnicodeLen); NS_ENSURE_SUCCESS(rv, rv); - if (!buffer.SetLength(outUnicodeLen, fallible_t())) + if (!buffer.SetLength(outUnicodeLen, fallible)) return NS_ERROR_OUT_OF_MEMORY; rv = aUnicodeDecoder->Convert(aString.get(), &numberOfBytes, buffer.BeginWriting(), &outUnicodeLen); diff --git a/dom/storage/DOMStorage.cpp b/dom/storage/DOMStorage.cpp index 121ed5486daf..a147fedebaf9 100644 --- a/dom/storage/DOMStorage.cpp +++ b/dom/storage/DOMStorage.cpp @@ -117,7 +117,7 @@ DOMStorage::SetItem(const nsAString& aKey, const nsAString& aData, : Telemetry::SESSIONDOMSTORAGE_VALUE_SIZE_BYTES, aData.Length()); nsString data; - bool ok = data.Assign(aData, fallible_t()); + bool ok = data.Assign(aData, fallible); if (!ok) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; diff --git a/dom/svg/SVGContentUtils.h b/dom/svg/SVGContentUtils.h index 9c4e71afa82c..be709df33dbd 100644 --- a/dom/svg/SVGContentUtils.h +++ b/dom/svg/SVGContentUtils.h @@ -10,7 +10,6 @@ #define _USE_MATH_DEFINES #include -#include "mozilla/fallible.h" #include "mozilla/gfx/2D.h" // for StrokeOptions #include "mozilla/gfx/Matrix.h" #include "mozilla/RangedPtr.h" @@ -111,8 +110,7 @@ public: mDashPattern = mSmallArray; return mSmallArray; } - static const mozilla::fallible_t fallible = mozilla::fallible_t(); - Float* nonConstArray = new (fallible) Float[aDashCount]; + Float* nonConstArray = new (mozilla::fallible) Float[aDashCount]; mDashPattern = nonConstArray; return nonConstArray; } diff --git a/dom/svg/SVGFEConvolveMatrixElement.cpp b/dom/svg/SVGFEConvolveMatrixElement.cpp index 72b8e7c6c7fe..328220d1186b 100644 --- a/dom/svg/SVGFEConvolveMatrixElement.cpp +++ b/dom/svg/SVGFEConvolveMatrixElement.cpp @@ -202,7 +202,6 @@ SVGFEConvolveMatrixElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstan if (orderX > NS_SVG_OFFSCREEN_MAX_DIMENSION || orderY > NS_SVG_OFFSCREEN_MAX_DIMENSION) return failureDescription; - const fallible_t fallible = fallible_t(); nsAutoArrayPtr kernel(new (fallible) float[orderX * orderY]); if (!kernel) return failureDescription; diff --git a/dom/xslt/base/txDouble.cpp b/dom/xslt/base/txDouble.cpp index 1153a12a2f78..f52d1b885163 100644 --- a/dom/xslt/base/txDouble.cpp +++ b/dom/xslt/base/txDouble.cpp @@ -179,7 +179,7 @@ void txDouble::toString(double aValue, nsAString& aDest) ++length; // grow the string uint32_t oldlength = aDest.Length(); - if (!aDest.SetLength(oldlength + length, mozilla::fallible_t())) + if (!aDest.SetLength(oldlength + length, mozilla::fallible)) return; // out of memory nsAString::iterator dest; aDest.BeginWriting(dest).advance(int32_t(oldlength)); diff --git a/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp b/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp index ce23e208f26d..ad18c4fb2dea 100644 --- a/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp +++ b/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp @@ -514,7 +514,7 @@ txXPathNodeUtils::appendNodeValue(const txXPathNode& aNode, nsAString& aResult) aNode.mNode->IsElement() || aNode.mNode->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT)) { nsContentUtils::AppendNodeTextContent(aNode.mNode, true, aResult, - mozilla::fallible_t()); + mozilla::fallible); return; } diff --git a/editor/libeditor/nsTextEditRules.cpp b/editor/libeditor/nsTextEditRules.cpp index 2da4bc29c68d..21eee05a76ba 100644 --- a/editor/libeditor/nsTextEditRules.cpp +++ b/editor/libeditor/nsTextEditRules.cpp @@ -1198,7 +1198,7 @@ nsTextEditRules::TruncateInsertionIfNeeded(Selection* aSelection, if (!aSelection || !aInString || !aOutString) {return NS_ERROR_NULL_POINTER;} nsresult res = NS_OK; - if (!aOutString->Assign(*aInString, mozilla::fallible_t())) { + if (!aOutString->Assign(*aInString, mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } if (aTruncated) { diff --git a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp index dbc0ae1e1ce7..967de5da4089 100644 --- a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp +++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp @@ -576,7 +576,7 @@ mozInlineSpellWordUtil::BuildSoftText() DOMTextMapping(NodeOffset(node, firstOffsetInNode), mSoftText.Length(), len)); bool ok = textFragment->AppendTo(mSoftText, firstOffsetInNode, len, - mozilla::fallible_t()); + mozilla::fallible); if (!ok) { // probably out of memory, remove from mSoftTextDOMMapping mSoftTextDOMMapping.RemoveElementAt(mSoftTextDOMMapping.Length() - 1); diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index 7ab4ff74aed9..65fff190eda3 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -674,8 +674,7 @@ bool MemoryTextureClient::Allocate(uint32_t aSize) { MOZ_ASSERT(!mBuffer); - static const fallible_t fallible = fallible_t(); - mBuffer = new(fallible) uint8_t[aSize]; + mBuffer = new (fallible) uint8_t[aSize]; if (!mBuffer) { NS_WARNING("Failed to allocate buffer"); return false; diff --git a/gfx/thebes/gfxFT2FontList.cpp b/gfx/thebes/gfxFT2FontList.cpp index b2ecec736b60..471cdb5900cc 100644 --- a/gfx/thebes/gfxFT2FontList.cpp +++ b/gfx/thebes/gfxFT2FontList.cpp @@ -1096,7 +1096,6 @@ gfxFT2FontList::AppendFacesFromOmnijarEntry(nsZipArchive* aArchive, uint32_t bufSize = item->RealSize(); // We use fallible allocation here; if there's not enough RAM, we'll simply // ignore the bundled fonts and fall back to the device's installed fonts. - static const fallible_t fallible = fallible_t(); nsAutoArrayPtr buf(new (fallible) uint8_t[bufSize]); if (!buf) { return; diff --git a/image/decoders/icon/win/nsIconChannel.cpp b/image/decoders/icon/win/nsIconChannel.cpp index 4ce126de06a4..4f1fb717501a 100644 --- a/image/decoders/icon/win/nsIconChannel.cpp +++ b/image/decoders/icon/win/nsIconChannel.cpp @@ -490,7 +490,7 @@ CreateBitmapInfo(BITMAPINFOHEADER* aHeader, size_t aColorTableSize) { BITMAPINFO* bmi = (BITMAPINFO*) ::operator new(sizeof(BITMAPINFOHEADER) + aColorTableSize, - mozilla::fallible_t()); + mozilla::fallible); if (bmi) { memcpy(bmi, aHeader, sizeof(BITMAPINFOHEADER)); memset(bmi->bmiColors, 0, aColorTableSize); diff --git a/image/encoders/bmp/nsBMPEncoder.cpp b/image/encoders/bmp/nsBMPEncoder.cpp index 91ec88375c6b..7fd00e591685 100644 --- a/image/encoders/bmp/nsBMPEncoder.cpp +++ b/image/encoders/bmp/nsBMPEncoder.cpp @@ -185,7 +185,6 @@ nsBMPEncoder::AddImageFrame(const uint8_t* aData, return NS_ERROR_INVALID_ARG; } - static fallible_t fallible = fallible_t(); nsAutoArrayPtr row(new (fallible) uint8_t[mBMPInfoHeader.width * BytesPerPixel(mBMPInfoHeader.bpp)]); diff --git a/image/src/SourceBuffer.h b/image/src/SourceBuffer.h index 0383d5c02401..34c9b0ed93e1 100644 --- a/image/src/SourceBuffer.h +++ b/image/src/SourceBuffer.h @@ -272,7 +272,6 @@ private: , mLength(0) { MOZ_ASSERT(aCapacity > 0, "Creating zero-capacity chunk"); - static const fallible_t fallible = fallible_t(); mData = new (fallible) char[mCapacity]; } diff --git a/intl/uconv/nsScriptableUConv.cpp b/intl/uconv/nsScriptableUConv.cpp index 49a8221a3b98..8bca5060544f 100644 --- a/intl/uconv/nsScriptableUConv.cpp +++ b/intl/uconv/nsScriptableUConv.cpp @@ -65,7 +65,7 @@ nsScriptableUnicodeConverter::ConvertFromUnicode(const nsAString& aSrc, nsresult rv = ConvertFromUnicodeWithLength(aSrc, &len, &str); if (NS_SUCCEEDED(rv)) { // No Adopt on nsACString :( - if (!_retval.Assign(str, len, mozilla::fallible_t())) { + if (!_retval.Assign(str, len, mozilla::fallible)) { rv = NS_ERROR_OUT_OF_MEMORY; } moz_free(str); @@ -114,7 +114,7 @@ nsScriptableUnicodeConverter::Finish(nsACString& _retval) nsresult rv = FinishWithLength(&str, &len); if (NS_SUCCEEDED(rv)) { // No Adopt on nsACString :( - if (!_retval.Assign(str, len, mozilla::fallible_t())) { + if (!_retval.Assign(str, len, mozilla::fallible)) { rv = NS_ERROR_OUT_OF_MEMORY; } moz_free(str); @@ -160,7 +160,7 @@ nsScriptableUnicodeConverter::ConvertFromByteArray(const uint8_t* aData, if (NS_SUCCEEDED(rv)) { buf[outLength] = 0; - if (!_retval.Assign(buf, outLength, mozilla::fallible_t())) { + if (!_retval.Assign(buf, outLength, mozilla::fallible)) { rv = NS_ERROR_OUT_OF_MEMORY; } } diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp index a9587a7ed2f3..b812028b9821 100644 --- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -2220,7 +2220,7 @@ void nsBidiPresUtils::CopyLogicalToVisual(const nsAString& aSource, uint32_t srcLength = aSource.Length(); if (srcLength == 0) return; - if (!aDest.SetLength(srcLength, fallible_t())) { + if (!aDest.SetLength(srcLength, fallible)) { return; } nsAString::const_iterator fromBegin, fromEnd; diff --git a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp index 8450f51308ea..25bd478c9bc0 100644 --- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp +++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp @@ -1009,7 +1009,6 @@ void MediaPipelineTransmit::PipelineListener::ProcessVideoChunk( // Send a black image. nsAutoArrayPtr pixelData; - static const fallible_t fallible = fallible_t(); pixelData = new (fallible) uint8_t[length]; if (pixelData) { // YCrCb black = 0x10 0x80 0x80 diff --git a/memory/mozalloc/fallible.h b/memory/fallible/fallible.cpp similarity index 63% rename from memory/mozalloc/fallible.h rename to memory/fallible/fallible.cpp index 0eedd11aca9d..f083fe674d55 100644 --- a/memory/mozalloc/fallible.h +++ b/memory/fallible/fallible.cpp @@ -2,13 +2,10 @@ * 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/. */ -#ifndef mozilla_fallible_h -#define mozilla_fallible_h +#include "fallible.h" namespace mozilla { -struct fallible_t { }; +const fallible_t fallible = {}; -} // namespace mozilla - -#endif // mozilla_fallible_h +} diff --git a/memory/fallible/fallible.h b/memory/fallible/fallible.h new file mode 100644 index 000000000000..0ae5d56dcf2e --- /dev/null +++ b/memory/fallible/fallible.h @@ -0,0 +1,67 @@ +/* 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/. */ + +#ifndef mozilla_fallible_h +#define mozilla_fallible_h + +#if defined(__cplusplus) + +/* Explicit fallible allocation + * + * Memory allocation (normally) defaults to abort in case of failed + * allocation. That is, it never returns NULL, and crashes instead. + * + * Code can explicitely request for fallible memory allocation thanks + * to the declarations below. + * + * The typical use of the mozilla::fallible const is with placement new, + * like the following: + * + * foo = new (mozilla::fallible) Foo(); + * + * The following forms, or derivatives, are also possible but deprecated: + * + * foo = new ((mozilla::fallible_t())) Foo(); + * + * const mozilla::fallible_t fallible = mozilla::fallible_t(); + * bar = new (f) Bar(); + * + * It is also possible to declare method overloads with fallible allocation + * alternatives, like so: + * + * class Foo { + * public: + * void Method(void *); + * void Method(void *, const mozilla::fallible_t&); + * }; + * + * Foo foo; + * foo.Method(nullptr, mozilla::fallible); + * + * If that last method call is in a method that itself takes a const + * fallible_t& argument, it is recommended to propagate that argument + * instead of using mozilla::fallible: + * + * void Func(Foo &foo, const mozilla::fallible_t& aFallible) { + * foo.Method(nullptr, aFallible); + * } + * + */ +namespace mozilla { + +struct fallible_t { }; + +/* This symbol is kept unexported, such that in corner cases where the + * compiler can't remove its use (essentially, cross compilation-unit + * calls), the smallest machine code is used. + * Depending how the linker packs symbols, it will consume between 1 and + * 8 bytes of read-only data in each executable or shared library, but + * only in those where it's actually not optimized out by the compiler. + */ +extern const fallible_t fallible; + +} // namespace mozilla +#endif + +#endif // mozilla_fallible_h diff --git a/memory/fallible/moz.build b/memory/fallible/moz.build new file mode 100644 index 000000000000..5ef8fe0bbada --- /dev/null +++ b/memory/fallible/moz.build @@ -0,0 +1,30 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +EXPORTS.mozilla += [ + 'fallible.h', +] + +Library('fallible') + +SOURCES += [ + 'fallible.cpp', +] + +if CONFIG['_MSC_VER']: + # MSVC normally adds linker directives relative to the CRT in a .drectve + # section in .obj files. Then, when linking objects, it adds those + # directives as if they were given as command line arguments. This can + # lead to trying to include link CRTs because different objects are + # compiled with different CRT options (i.e. -MT vs. -MD), and failing. + # The only source in this directory doesn't expose anything that depends + # on a CRT, so it doesn't need to be bound to a specific one. + # Adding the -Zl option makes MSVC not store linker directives in the + # object. This allows to link fallible.obj to binaries independently of + # the CRT they use. + CXXFLAGS += [ + '-Zl', + ] diff --git a/memory/mozalloc/moz.build b/memory/mozalloc/moz.build index 72640496c416..3f952879959b 100644 --- a/memory/mozalloc/moz.build +++ b/memory/mozalloc/moz.build @@ -6,7 +6,6 @@ NO_VISIBILITY_FLAGS = True EXPORTS.mozilla += [ - 'fallible.h', 'mozalloc.h', 'mozalloc_abort.h', 'mozalloc_oom.h', diff --git a/modules/libjar/nsZipArchive.cpp b/modules/libjar/nsZipArchive.cpp index 28f8d8f2f2f4..c0228d92f92a 100644 --- a/modules/libjar/nsZipArchive.cpp +++ b/modules/libjar/nsZipArchive.cpp @@ -1157,7 +1157,7 @@ nsZipItemPtr_base::nsZipItemPtr_base(nsZipArchive *aZip, const char * aEntryName uint32_t size = 0; if (item->Compression() == DEFLATED) { size = item->RealSize(); - mAutoBuf = new ((fallible_t())) uint8_t[size]; + mAutoBuf = new (fallible) uint8_t[size]; if (!mAutoBuf) { return; } diff --git a/modules/libpref/nsPrefBranch.cpp b/modules/libpref/nsPrefBranch.cpp index 5135fe461378..3c2fd845c0c4 100644 --- a/modules/libpref/nsPrefBranch.cpp +++ b/modules/libpref/nsPrefBranch.cpp @@ -330,7 +330,7 @@ NS_IMETHODIMP nsPrefBranch::GetComplexValue(const char *aPrefName, const nsIID & // Debugging to see why we end up with very long strings here with // some addons, see bug 836263. nsAutoString wdata; - if (!AppendUTF8toUTF16(utf8String, wdata, mozilla::fallible_t())) { + if (!AppendUTF8toUTF16(utf8String, wdata, mozilla::fallible)) { #ifdef MOZ_CRASHREPORTER nsCOMPtr cr = do_GetService("@mozilla.org/toolkit/crash-reporter;1"); diff --git a/modules/libpref/prefapi.cpp b/modules/libpref/prefapi.cpp index 467663e36461..d0ce8bef0e52 100644 --- a/modules/libpref/prefapi.cpp +++ b/modules/libpref/prefapi.cpp @@ -147,7 +147,7 @@ nsresult PREF_Init() { if (!gHashTable.IsInitialized()) { if (!PL_DHashTableInit(&gHashTable, &pref_HashTableOps, - sizeof(PrefHashEntry), fallible_t(), + sizeof(PrefHashEntry), fallible, PREF_HASHTABLE_INITIAL_LENGTH)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/moz.build b/moz.build index 1c97f6f9b5c0..abd2f5ebf1f6 100644 --- a/moz.build +++ b/moz.build @@ -43,6 +43,7 @@ if not CONFIG['LIBXUL_SDK']: DIRS += [ 'mozglue', + 'memory/fallible', 'memory/mozalloc', 'memory/volatile', ] diff --git a/netwerk/base/nsBufferedStreams.cpp b/netwerk/base/nsBufferedStreams.cpp index 4c44e7f12075..36041d63fbd5 100644 --- a/netwerk/base/nsBufferedStreams.cpp +++ b/netwerk/base/nsBufferedStreams.cpp @@ -71,8 +71,7 @@ nsBufferedStream::Init(nsISupports* stream, uint32_t bufferSize) mBufferSize = bufferSize; mBufferStartOffset = 0; mCursor = 0; - const mozilla::fallible_t fallible = mozilla::fallible_t(); - mBuffer = new (fallible) char[bufferSize]; + mBuffer = new (mozilla::fallible) char[bufferSize]; if (mBuffer == nullptr) return NS_ERROR_OUT_OF_MEMORY; return NS_OK; diff --git a/netwerk/base/nsNetUtil.h b/netwerk/base/nsNetUtil.h index d4a5d5dbad77..218f91d73d52 100644 --- a/netwerk/base/nsNetUtil.h +++ b/netwerk/base/nsNetUtil.h @@ -1546,7 +1546,7 @@ NS_ReadInputStreamToString(nsIInputStream *aInputStream, nsACString &aDest, uint32_t aCount) { - if (!aDest.SetLength(aCount, mozilla::fallible_t())) + if (!aDest.SetLength(aCount, mozilla::fallible)) return NS_ERROR_OUT_OF_MEMORY; void* dest = aDest.BeginWriting(); return NS_ReadInputStreamToBuffer(aInputStream, &dest, aCount); diff --git a/netwerk/base/nsStandardURL.cpp b/netwerk/base/nsStandardURL.cpp index 47015ed16bfb..d21e25e8c35e 100644 --- a/netwerk/base/nsStandardURL.cpp +++ b/netwerk/base/nsStandardURL.cpp @@ -588,7 +588,7 @@ nsStandardURL::BuildNormalizedSpec(const char *spec) // generate the normalized URL string // // approxLen should be correct or 1 high - if (!mSpec.SetLength(approxLen+1, mozilla::fallible_t())) // buf needs a trailing '\0' below + if (!mSpec.SetLength(approxLen+1, mozilla::fallible)) // buf needs a trailing '\0' below return NS_ERROR_OUT_OF_MEMORY; char *buf; mSpec.BeginWriting(buf); diff --git a/netwerk/base/nsUnicharStreamLoader.cpp b/netwerk/base/nsUnicharStreamLoader.cpp index 9c9dc963c626..383bed9d0df3 100644 --- a/netwerk/base/nsUnicharStreamLoader.cpp +++ b/netwerk/base/nsUnicharStreamLoader.cpp @@ -26,7 +26,7 @@ nsUnicharStreamLoader::Init(nsIUnicharStreamLoaderObserver *aObserver) mObserver = aObserver; - if (!mRawData.SetCapacity(SNIFFING_BUFFER_SIZE, fallible_t())) + if (!mRawData.SetCapacity(SNIFFING_BUFFER_SIZE, fallible)) return NS_ERROR_OUT_OF_MEMORY; return NS_OK; @@ -214,7 +214,7 @@ nsUnicharStreamLoader::WriteSegmentFun(nsIInputStream *, self->mDecoder->GetMaxLength(aSegment, srcLen, &dstLen); uint32_t capacity = haveRead + dstLen; - if (!self->mBuffer.SetCapacity(capacity, fallible_t())) { + if (!self->mBuffer.SetCapacity(capacity, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/netwerk/cache/nsCacheEntry.cpp b/netwerk/cache/nsCacheEntry.cpp index 60c4e51bc764..7149bbfab687 100644 --- a/netwerk/cache/nsCacheEntry.cpp +++ b/netwerk/cache/nsCacheEntry.cpp @@ -405,7 +405,7 @@ nsCacheEntryHashTable::Init() nsresult rv = NS_OK; initialized = PL_DHashTableInit(&table, &ops, sizeof(nsCacheEntryHashTableEntry), - fallible_t(), 256); + fallible, 256); if (!initialized) rv = NS_ERROR_OUT_OF_MEMORY; diff --git a/netwerk/cache/nsDiskCacheDeviceSQL.cpp b/netwerk/cache/nsDiskCacheDeviceSQL.cpp index 3e44aa7d5397..dd1774c9b0fd 100644 --- a/netwerk/cache/nsDiskCacheDeviceSQL.cpp +++ b/netwerk/cache/nsDiskCacheDeviceSQL.cpp @@ -966,7 +966,7 @@ nsOfflineCacheDevice::UpdateEntry(nsCacheEntry *entry) nsCString metaDataBuf; uint32_t mdSize = entry->MetaDataSize(); - if (!metaDataBuf.SetLength(mdSize, fallible_t())) + if (!metaDataBuf.SetLength(mdSize, fallible)) return NS_ERROR_OUT_OF_MEMORY; char *md = metaDataBuf.BeginWriting(); entry->FlattenMetaData(md, mdSize); diff --git a/netwerk/protocol/http/nsHttp.cpp b/netwerk/protocol/http/nsHttp.cpp index 8cc0162cec35..5f10195744e4 100644 --- a/netwerk/protocol/http/nsHttp.cpp +++ b/netwerk/protocol/http/nsHttp.cpp @@ -106,7 +106,7 @@ nsHttp::CreateAtomTable() // known atoms (NUM_HTTP_ATOMS) because we expect to encounter a few random // headers right off the bat. if (!PL_DHashTableInit(&sAtomTable, &ops, sizeof(PLDHashEntryStub), - fallible_t(), NUM_HTTP_ATOMS + 10)) { + fallible, NUM_HTTP_ATOMS + 10)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp index e7ea9f2032ad..0187ffbb2a58 100644 --- a/netwerk/protocol/websocket/WebSocketChannel.cpp +++ b/netwerk/protocol/websocket/WebSocketChannel.cpp @@ -1609,7 +1609,7 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count) utf8Data.Length())); } else { if (!utf8Data.Assign((const char *)payload, payloadLength, - mozilla::fallible_t())) { + mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } } @@ -1719,7 +1719,7 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count) binaryData.Length())); } else { if (!binaryData.Assign((const char *)payload, payloadLength, - mozilla::fallible_t())) { + mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } } diff --git a/netwerk/streamconv/converters/nsDirIndexParser.cpp b/netwerk/streamconv/converters/nsDirIndexParser.cpp index f68d3df3b899..abfce2f1d0b0 100644 --- a/netwerk/streamconv/converters/nsDirIndexParser.cpp +++ b/netwerk/streamconv/converters/nsDirIndexParser.cpp @@ -333,7 +333,7 @@ nsDirIndexParser::OnDataAvailable(nsIRequest *aRequest, nsISupports *aCtxt, // Ensure that our mBuf has capacity to hold the data we're about to // read. - if (!mBuf.SetLength(len + aCount, fallible_t())) + if (!mBuf.SetLength(len + aCount, fallible)) return NS_ERROR_OUT_OF_MEMORY; // Now read the data into our buffer. diff --git a/parser/html/nsHtml5OwningUTF16Buffer.cpp b/parser/html/nsHtml5OwningUTF16Buffer.cpp index dcd2aec196a7..45bbb70dc5f9 100644 --- a/parser/html/nsHtml5OwningUTF16Buffer.cpp +++ b/parser/html/nsHtml5OwningUTF16Buffer.cpp @@ -39,13 +39,12 @@ nsHtml5OwningUTF16Buffer::~nsHtml5OwningUTF16Buffer() already_AddRefed nsHtml5OwningUTF16Buffer::FalliblyCreate(int32_t aLength) { - const mozilla::fallible_t fallible = mozilla::fallible_t(); - char16_t* newBuf = new (fallible) char16_t[aLength]; + char16_t* newBuf = new (mozilla::fallible) char16_t[aLength]; if (!newBuf) { return nullptr; } nsRefPtr newObj = - new (fallible) nsHtml5OwningUTF16Buffer(newBuf); + new (mozilla::fallible) nsHtml5OwningUTF16Buffer(newBuf); if (!newObj) { delete[] newBuf; return nullptr; diff --git a/parser/html/nsHtml5StreamParser.cpp b/parser/html/nsHtml5StreamParser.cpp index 9c58ef10e025..536f139ab8c2 100644 --- a/parser/html/nsHtml5StreamParser.cpp +++ b/parser/html/nsHtml5StreamParser.cpp @@ -771,8 +771,7 @@ nsHtml5StreamParser::SniffStreamBytes(const uint8_t* aFromSegment, } if (!mSniffingBuffer) { - const mozilla::fallible_t fallible = mozilla::fallible_t(); - mSniffingBuffer = new (fallible) + mSniffingBuffer = new (mozilla::fallible) uint8_t[NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE]; if (!mSniffingBuffer) { return NS_ERROR_OUT_OF_MEMORY; @@ -1146,8 +1145,7 @@ nsHtml5StreamParser::OnDataAvailable(nsIRequest* aRequest, uint32_t totalRead; // Main thread to parser thread dispatch requires copying to buffer first. if (NS_IsMainThread()) { - const mozilla::fallible_t fallible = mozilla::fallible_t(); - nsAutoArrayPtr data(new (fallible) uint8_t[aLength]); + nsAutoArrayPtr data(new (mozilla::fallible) uint8_t[aLength]); if (!data) { return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY); } diff --git a/parser/htmlparser/nsHTMLEntities.cpp b/parser/htmlparser/nsHTMLEntities.cpp index b69c8ddf4440..ad2cdf3123b2 100644 --- a/parser/htmlparser/nsHTMLEntities.cpp +++ b/parser/htmlparser/nsHTMLEntities.cpp @@ -85,12 +85,12 @@ nsHTMLEntities::AddRefTable(void) if (!gTableRefCnt) { if (!PL_DHashTableInit(&gEntityToUnicode, &EntityToUnicodeOps, sizeof(EntityNodeEntry), - fallible_t(), NS_HTML_ENTITY_COUNT)) { + fallible, NS_HTML_ENTITY_COUNT)) { return NS_ERROR_OUT_OF_MEMORY; } if (!PL_DHashTableInit(&gUnicodeToEntity, &UnicodeToEntityOps, sizeof(EntityNodeEntry), - fallible_t(), NS_HTML_ENTITY_COUNT)) { + fallible, NS_HTML_ENTITY_COUNT)) { PL_DHashTableFinish(&gEntityToUnicode); return NS_ERROR_OUT_OF_MEMORY; } diff --git a/parser/htmlparser/nsScannerString.cpp b/parser/htmlparser/nsScannerString.cpp index a596498e9bfc..45e3d7f16c71 100644 --- a/parser/htmlparser/nsScannerString.cpp +++ b/parser/htmlparser/nsScannerString.cpp @@ -472,7 +472,7 @@ CopyUnicodeTo( const nsScannerIterator& aSrcStart, nsAString& aDest ) { nsAString::iterator writer; - if (!aDest.SetLength(Distance(aSrcStart, aSrcEnd), mozilla::fallible_t())) { + if (!aDest.SetLength(Distance(aSrcStart, aSrcEnd), mozilla::fallible)) { aDest.Truncate(); return; // out of memory } @@ -505,7 +505,7 @@ AppendUnicodeTo( const nsScannerIterator& aSrcStart, { nsAString::iterator writer; uint32_t oldLength = aDest.Length(); - if (!aDest.SetLength(oldLength + Distance(aSrcStart, aSrcEnd), mozilla::fallible_t())) + if (!aDest.SetLength(oldLength + Distance(aSrcStart, aSrcEnd), mozilla::fallible)) return; // out of memory aDest.BeginWriting(writer).advance(oldLength); nsScannerIterator fromBegin(aSrcStart); diff --git a/security/manager/ssl/src/nsCertTree.cpp b/security/manager/ssl/src/nsCertTree.cpp index f7d82d9876bc..c041079629b9 100644 --- a/security/manager/ssl/src/nsCertTree.cpp +++ b/security/manager/ssl/src/nsCertTree.cpp @@ -182,7 +182,7 @@ nsresult nsCertTree::InitCompareHash() { ClearCompareHash(); if (!PL_DHashTableInit(&mCompareCache, &gMapOps, - sizeof(CompareCacheHashEntryPtr), fallible_t(), 64)) { + sizeof(CompareCacheHashEntryPtr), fallible, 64)) { return NS_ERROR_OUT_OF_MEMORY; } return NS_OK; diff --git a/services/crypto/component/nsSyncJPAKE.cpp b/services/crypto/component/nsSyncJPAKE.cpp index 5c3a3b1265ca..e72e908193aa 100644 --- a/services/crypto/component/nsSyncJPAKE.cpp +++ b/services/crypto/component/nsSyncJPAKE.cpp @@ -16,7 +16,7 @@ #include #include -using mozilla::fallible_t; +using mozilla::fallible; static bool hex_from_2char(const unsigned char *c2, unsigned char *byteval) @@ -73,7 +73,7 @@ static bool toHexString(const unsigned char * str, unsigned len, nsACString & out) { static const char digits[] = "0123456789ABCDEF"; - if (!out.SetCapacity(2 * len, fallible_t())) + if (!out.SetCapacity(2 * len, fallible)) return false; out.SetLength(0); for (unsigned i = 0; i < len; ++i) { @@ -301,7 +301,7 @@ setBase64(const unsigned char * data, unsigned len, nsACString & out) if (base64 != nullptr) { size_t len = PORT_Strlen(base64); - if (out.SetCapacity(len, fallible_t())) { + if (out.SetCapacity(len, fallible)) { out.SetLength(0); out.Append(base64, len); PORT_Free((void*) base64); diff --git a/toolkit/components/downloads/SQLFunctions.cpp b/toolkit/components/downloads/SQLFunctions.cpp index 883c993b0896..7540d39b7a47 100644 --- a/toolkit/components/downloads/SQLFunctions.cpp +++ b/toolkit/components/downloads/SQLFunctions.cpp @@ -61,7 +61,7 @@ Base64urlEncode(const uint8_t* aBytes, // result, we set the capacity to be one greater than what we need, and the // length to our desired length. uint32_t length = (aNumBytes + 2) / 3 * 4; // +2 due to integer math. - NS_ENSURE_TRUE(_result.SetCapacity(length + 1, mozilla::fallible_t()), + NS_ENSURE_TRUE(_result.SetCapacity(length + 1, mozilla::fallible), NS_ERROR_OUT_OF_MEMORY); _result.SetLength(length); (void)PL_Base64Encode(reinterpret_cast(aBytes), aNumBytes, diff --git a/toolkit/components/places/Helpers.cpp b/toolkit/components/places/Helpers.cpp index 27298f871026..5688b73d8ed1 100644 --- a/toolkit/components/places/Helpers.cpp +++ b/toolkit/components/places/Helpers.cpp @@ -212,7 +212,7 @@ Base64urlEncode(const uint8_t* aBytes, // result, we set the capacity to be one greater than what we need, and the // length to our desired length. uint32_t length = (aNumBytes + 2) / 3 * 4; // +2 due to integer math. - NS_ENSURE_TRUE(_result.SetCapacity(length + 1, fallible_t()), + NS_ENSURE_TRUE(_result.SetCapacity(length + 1, fallible), NS_ERROR_OUT_OF_MEMORY); _result.SetLength(length); (void)PL_Base64Encode(reinterpret_cast(aBytes), aNumBytes, diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/Telemetry.cpp index e48056ac2211..a1c03008b9c6 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -1793,7 +1793,7 @@ TelemetryImpl::NewKeyedHistogram(const nsACString &name, const nsACString &expir KeyedHistogram* keyed = new KeyedHistogram(name, expiration, histogramType, min, max, bucketCount); - if (MOZ_UNLIKELY(!mKeyedHistograms.Put(name, keyed, fallible_t()))) { + if (MOZ_UNLIKELY(!mKeyedHistograms.Put(name, keyed, fallible))) { delete keyed; return NS_ERROR_OUT_OF_MEMORY; } diff --git a/widget/windows/nsIMM32Handler.cpp b/widget/windows/nsIMM32Handler.cpp index 6aaae7bc45a7..e5a922d0fbb6 100644 --- a/widget/windows/nsIMM32Handler.cpp +++ b/widget/windows/nsIMM32Handler.cpp @@ -1689,7 +1689,7 @@ nsIMM32Handler::GetCompositionString(const nsIMEContext &aIMEContext, long lRtn = ::ImmGetCompositionStringW(aIMEContext.get(), aIndex, nullptr, 0); if (lRtn < 0 || !aCompositionString.SetLength((lRtn / sizeof(WCHAR)) + 1, - mozilla::fallible_t())) { + mozilla::fallible)) { PR_LOG(gIMM32Log, PR_LOG_ALWAYS, ("IMM32: GetCompositionString, FAILED by OOM\n")); return; // Error or out of memory. @@ -1756,7 +1756,7 @@ nsIMM32Handler::ConvertToANSIString(const nsAFlatString& aStr, UINT aCodePage, nullptr, 0, nullptr, nullptr); NS_ENSURE_TRUE(len >= 0, false); - if (!aANSIStr.SetLength(len, mozilla::fallible_t())) { + if (!aANSIStr.SetLength(len, mozilla::fallible)) { PR_LOG(gIMM32Log, PR_LOG_ALWAYS, ("IMM32: ConvertToANSIString, FAILED by OOM\n")); return false; diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index 71ea2d6cce1e..30077dd8ed3a 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -1357,7 +1357,7 @@ private: if (!aPi) { MOZ_CRASH(); } - if (!aQueue.Push(aPi, fallible_t())) { + if (!aQueue.Push(aPi, fallible)) { mVisitor.Failed(); } } diff --git a/xpcom/ds/nsStaticNameTable.cpp b/xpcom/ds/nsStaticNameTable.cpp index 50a39645c0ea..6d8950cf15e3 100644 --- a/xpcom/ds/nsStaticNameTable.cpp +++ b/xpcom/ds/nsStaticNameTable.cpp @@ -139,7 +139,7 @@ nsStaticCaseInsensitiveNameTable::Init(const char* const aNames[], } if (!PL_DHashTableInit(&mNameTable, &nametable_CaseInsensitiveHashTableOps, - sizeof(NameTableEntry), fallible_t(), + sizeof(NameTableEntry), fallible, aLength)) { return false; } diff --git a/xpcom/ds/nsSupportsPrimitives.cpp b/xpcom/ds/nsSupportsPrimitives.cpp index 6fd41bb8a09f..34235ce8f47c 100644 --- a/xpcom/ds/nsSupportsPrimitives.cpp +++ b/xpcom/ds/nsSupportsPrimitives.cpp @@ -7,8 +7,6 @@ #include "nsMemory.h" #include "prprf.h" -using mozilla::fallible_t; - /***************************************************************************/ NS_IMPL_ISUPPORTS(nsSupportsIDImpl, nsISupportsID, nsISupportsPrimitive) @@ -107,7 +105,7 @@ nsSupportsCStringImpl::ToString(char** aResult) NS_IMETHODIMP nsSupportsCStringImpl::SetData(const nsACString& aData) { - bool ok = mData.Assign(aData, fallible_t()); + bool ok = mData.Assign(aData, mozilla::fallible); if (!ok) { return NS_ERROR_OUT_OF_MEMORY; } @@ -152,7 +150,7 @@ nsSupportsStringImpl::ToString(char16_t** aResult) NS_IMETHODIMP nsSupportsStringImpl::SetData(const nsAString& aData) { - bool ok = mData.Assign(aData, fallible_t()); + bool ok = mData.Assign(aData, mozilla::fallible); if (!ok) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/xpcom/glue/moz.build b/xpcom/glue/moz.build index 0b296745023c..27c6d1473b2d 100644 --- a/xpcom/glue/moz.build +++ b/xpcom/glue/moz.build @@ -114,3 +114,8 @@ if CONFIG['ENABLE_TESTS']: DIRS += ['tests/gtest'] FAIL_ON_WARNINGS = True + +# Include fallible for third party code using the xpcom glue +USE_LIBS += [ + 'fallible', +] diff --git a/xpcom/glue/nomozalloc/moz.build b/xpcom/glue/nomozalloc/moz.build index d74185497368..df53bca9bb71 100644 --- a/xpcom/glue/nomozalloc/moz.build +++ b/xpcom/glue/nomozalloc/moz.build @@ -42,3 +42,8 @@ USE_STATIC_LIBS = True DISABLE_STL_WRAPPING = True FAIL_ON_WARNINGS = True + +# Include fallible for third party code using the xpcom glue +USE_LIBS += [ + 'fallible', +] diff --git a/xpcom/glue/nsBaseHashtable.h b/xpcom/glue/nsBaseHashtable.h index 031048cc2236..7a701b8c35b6 100644 --- a/xpcom/glue/nsBaseHashtable.h +++ b/xpcom/glue/nsBaseHashtable.h @@ -123,7 +123,7 @@ public: */ void Put(KeyType aKey, const UserDataType& aData) { - if (!Put(aKey, aData, fallible_t())) { + if (!Put(aKey, aData, mozilla::fallible)) { NS_ABORT_OOM(this->mTable.EntrySize() * this->mTable.EntryCount()); } } diff --git a/xpcom/glue/nsDeque.h b/xpcom/glue/nsDeque.h index 279af93b6dd5..2f162d1ee9ae 100644 --- a/xpcom/glue/nsDeque.h +++ b/xpcom/glue/nsDeque.h @@ -84,7 +84,7 @@ public: */ void Push(void* aItem) { - if (!Push(aItem, fallible_t())) { + if (!Push(aItem, mozilla::fallible)) { NS_ABORT_OOM(mSize * sizeof(void*)); } } @@ -98,7 +98,7 @@ public: */ void PushFront(void* aItem) { - if (!PushFront(aItem, fallible_t())) { + if (!PushFront(aItem, mozilla::fallible)) { NS_ABORT_OOM(mSize * sizeof(void*)); } } diff --git a/xpcom/glue/nsRefPtrHashtable.h b/xpcom/glue/nsRefPtrHashtable.h index df9227893fdb..be9777d90650 100644 --- a/xpcom/glue/nsRefPtrHashtable.h +++ b/xpcom/glue/nsRefPtrHashtable.h @@ -147,7 +147,7 @@ void nsRefPtrHashtable::Put(KeyType aKey, already_AddRefed aData) { - if (!Put(aKey, mozilla::Move(aData), mozilla::fallible_t())) { + if (!Put(aKey, mozilla::Move(aData), mozilla::fallible)) { NS_ABORT_OOM(this->mTable.EntrySize() * this->mTable.EntryCount()); } } diff --git a/xpcom/glue/nsTHashtable.h b/xpcom/glue/nsTHashtable.h index 967df230be2e..2a0d5dc5e0d4 100644 --- a/xpcom/glue/nsTHashtable.h +++ b/xpcom/glue/nsTHashtable.h @@ -149,7 +149,7 @@ public: */ EntryType* PutEntry(KeyType aKey) { - EntryType* e = PutEntry(aKey, fallible_t()); + EntryType* e = PutEntry(aKey, mozilla::fallible); if (!e) { NS_ABORT_OOM(mTable.EntrySize() * mTable.EntryCount()); } diff --git a/xpcom/glue/pldhash.cpp b/xpcom/glue/pldhash.cpp index 6c8a1c86484f..3d95df386954 100644 --- a/xpcom/glue/pldhash.cpp +++ b/xpcom/glue/pldhash.cpp @@ -176,7 +176,7 @@ PL_NewDHashTable(const PLDHashTableOps* aOps, uint32_t aEntrySize, if (!table) { return nullptr; } - if (!PL_DHashTableInit(table, aOps, aEntrySize, fallible_t(), aLength)) { + if (!PL_DHashTableInit(table, aOps, aEntrySize, fallible, aLength)) { free(table); return nullptr; } @@ -276,7 +276,7 @@ void PL_DHashTableInit(PLDHashTable* aTable, const PLDHashTableOps* aOps, uint32_t aEntrySize, uint32_t aLength) { - if (!PL_DHashTableInit(aTable, aOps, aEntrySize, fallible_t(), aLength)) { + if (!PL_DHashTableInit(aTable, aOps, aEntrySize, fallible, aLength)) { if (aLength > PL_DHASH_MAX_INITIAL_LENGTH) { MOZ_CRASH(); // the asked-for length was too big } diff --git a/xpcom/glue/standalone/moz.build b/xpcom/glue/standalone/moz.build index 9942a3be49f7..a979e6b7fb91 100644 --- a/xpcom/glue/standalone/moz.build +++ b/xpcom/glue/standalone/moz.build @@ -44,3 +44,8 @@ LOCAL_INCLUDES += [ DISABLE_STL_WRAPPING = True FAIL_ON_WARNINGS = True + +# Include fallible for third party code using the xpcom glue +USE_LIBS += [ + 'fallible', +] diff --git a/xpcom/glue/standalone/staticruntime/moz.build b/xpcom/glue/standalone/staticruntime/moz.build index a4c84e56787c..cb9c24459892 100644 --- a/xpcom/glue/standalone/staticruntime/moz.build +++ b/xpcom/glue/standalone/staticruntime/moz.build @@ -39,3 +39,8 @@ USE_STATIC_LIBS = True DISABLE_STL_WRAPPING = True FAIL_ON_WARNINGS = True + +# Include fallible for third party code using the xpcom glue +USE_LIBS += [ + 'fallible', +] diff --git a/xpcom/glue/staticruntime/moz.build b/xpcom/glue/staticruntime/moz.build index 86b17efd1b35..aa4960825e79 100644 --- a/xpcom/glue/staticruntime/moz.build +++ b/xpcom/glue/staticruntime/moz.build @@ -37,3 +37,8 @@ USE_STATIC_LIBS = True DISABLE_STL_WRAPPING = True FAIL_ON_WARNINGS = True + +# Include fallible for third party code using the xpcom glue +USE_LIBS += [ + 'fallible', +] diff --git a/xpcom/io/Base64.cpp b/xpcom/io/Base64.cpp index 34e69bf3e814..91f1d54710e5 100644 --- a/xpcom/io/Base64.cpp +++ b/xpcom/io/Base64.cpp @@ -267,7 +267,7 @@ Base64Encode(const nsACString& aBinaryData, nsACString& aString) char* buffer; // Add one byte for null termination. - if (aString.SetCapacity(stringLen + 1, fallible_t()) && + if (aString.SetCapacity(stringLen + 1, fallible) && (buffer = aString.BeginWriting()) && PL_Base64Encode(aBinaryData.BeginReading(), aBinaryData.Length(), buffer)) { // PL_Base64Encode doesn't null terminate the buffer for us when we pass @@ -317,7 +317,7 @@ Base64Decode(const nsACString& aString, nsACString& aBinaryData) char* buffer; // Add one byte for null termination. - if (aBinaryData.SetCapacity(binaryDataLen + 1, fallible_t()) && + if (aBinaryData.SetCapacity(binaryDataLen + 1, fallible) && (buffer = aBinaryData.BeginWriting()) && PL_Base64Decode(aString.BeginReading(), aString.Length(), buffer)) { // PL_Base64Decode doesn't null terminate the buffer for us when we pass diff --git a/xpcom/io/SnappyCompressOutputStream.cpp b/xpcom/io/SnappyCompressOutputStream.cpp index a7485581d52c..89b8a08081e1 100644 --- a/xpcom/io/SnappyCompressOutputStream.cpp +++ b/xpcom/io/SnappyCompressOutputStream.cpp @@ -107,7 +107,7 @@ SnappyCompressOutputStream::WriteSegments(nsReadSegmentFun aReader, } if (!mBuffer) { - mBuffer.reset(new ((fallible_t())) char[mBlockSize]); + mBuffer.reset(new (fallible) char[mBlockSize]); if (NS_WARN_IF(!mBuffer)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -174,7 +174,7 @@ SnappyCompressOutputStream::FlushToBaseStream() // will then get re-used until the stream is closed. if (!mCompressedBuffer) { mCompressedBufferLength = MaxCompressedBufferLength(mBlockSize); - mCompressedBuffer.reset(new ((fallible_t())) char[mCompressedBufferLength]); + mCompressedBuffer.reset(new (fallible) char[mCompressedBufferLength]); if (NS_WARN_IF(!mCompressedBuffer)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/xpcom/io/SnappyUncompressInputStream.cpp b/xpcom/io/SnappyUncompressInputStream.cpp index 10fca0e85609..119b1af8e844 100644 --- a/xpcom/io/SnappyUncompressInputStream.cpp +++ b/xpcom/io/SnappyUncompressInputStream.cpp @@ -188,14 +188,14 @@ SnappyUncompressInputStream::ParseNextChunk(uint32_t* aBytesReadOut) // operation. These allocations only happens once. The buffers are reused // until the stream is closed. if (!mUncompressedBuffer) { - mUncompressedBuffer.reset(new ((fallible_t())) char[snappy::kBlockSize]); + mUncompressedBuffer.reset(new (fallible) char[snappy::kBlockSize]); if (NS_WARN_IF(!mUncompressedBuffer)) { return NS_ERROR_OUT_OF_MEMORY; } } if (!mCompressedBuffer) { - mCompressedBuffer.reset(new ((fallible_t())) char[kCompressedBufferLength]); + mCompressedBuffer.reset(new (fallible) char[kCompressedBufferLength]); if (NS_WARN_IF(!mCompressedBuffer)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/xpcom/io/nsBinaryStream.cpp b/xpcom/io/nsBinaryStream.cpp index fee287a4e129..289730f076c0 100644 --- a/xpcom/io/nsBinaryStream.cpp +++ b/xpcom/io/nsBinaryStream.cpp @@ -765,7 +765,7 @@ nsBinaryInputStream::ReadString(nsAString& aString) } // pre-allocate output buffer, and get direct access to buffer... - if (!aString.SetLength(length, mozilla::fallible_t())) { + if (!aString.SetLength(length, mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/xpcom/io/nsLocalFileWin.cpp b/xpcom/io/nsLocalFileWin.cpp index cacde9ae0966..e647e82112c2 100644 --- a/xpcom/io/nsLocalFileWin.cpp +++ b/xpcom/io/nsLocalFileWin.cpp @@ -3654,7 +3654,7 @@ nsDriveEnumerator::Init() * the length required for the string. */ DWORD length = GetLogicalDriveStringsW(0, 0); /* The string is null terminated */ - if (!mDrives.SetLength(length + 1, fallible_t())) { + if (!mDrives.SetLength(length + 1, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } if (!GetLogicalDriveStringsW(length, wwc(mDrives.BeginWriting()))) { diff --git a/xpcom/io/nsNativeCharsetUtils.cpp b/xpcom/io/nsNativeCharsetUtils.cpp index 8f7b500e45a4..447963e96634 100644 --- a/xpcom/io/nsNativeCharsetUtils.cpp +++ b/xpcom/io/nsNativeCharsetUtils.cpp @@ -814,7 +814,7 @@ NS_CopyNativeToUnicode(const nsACString& aInput, nsAString& aOutput) // this will generally result in a larger allocation, but that seems // better than an extra buffer copy. // - if (!aOutput.SetLength(inputLen, fallible_t())) { + if (!aOutput.SetLength(inputLen, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } nsAString::iterator out_iter; @@ -925,7 +925,7 @@ NS_CopyNativeToUnicode(const nsACString& aInput, nsAString& aOutput) } // allocate sufficient space - if (!aOutput.SetLength(resultLen, fallible_t())) { + if (!aOutput.SetLength(resultLen, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } if (resultLen > 0) { @@ -959,7 +959,7 @@ NS_CopyUnicodeToNative(const nsAString& aInput, nsACString& aOutput) } // allocate sufficient space - if (!aOutput.SetLength(resultLen, fallible_t())) { + if (!aOutput.SetLength(resultLen, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } if (resultLen > 0) { diff --git a/xpcom/string/nsAString.h b/xpcom/string/nsAString.h index 5ad82735d3f6..1925a4a8ecbf 100644 --- a/xpcom/string/nsAString.h +++ b/xpcom/string/nsAString.h @@ -14,8 +14,6 @@ #include #include -#include "mozilla/fallible.h" - #define kNotFound -1 // declare nsAString diff --git a/xpcom/string/nsReadableUtils.cpp b/xpcom/string/nsReadableUtils.cpp index 81b740e91e21..9de9fe71de4f 100644 --- a/xpcom/string/nsReadableUtils.cpp +++ b/xpcom/string/nsReadableUtils.cpp @@ -46,7 +46,7 @@ CopyASCIItoUTF16(const char* aSource, nsAString& aDest) void CopyUTF16toUTF8(const nsAString& aSource, nsACString& aDest) { - if (!CopyUTF16toUTF8(aSource, aDest, mozilla::fallible_t())) { + if (!CopyUTF16toUTF8(aSource, aDest, mozilla::fallible)) { // Note that this may wildly underestimate the allocation that failed, as // we report the length of aSource as UTF-16 instead of UTF-8. aDest.AllocFailed(aDest.Length() + aSource.Length()); @@ -55,10 +55,10 @@ CopyUTF16toUTF8(const nsAString& aSource, nsACString& aDest) bool CopyUTF16toUTF8(const nsAString& aSource, nsACString& aDest, - const mozilla::fallible_t&) + const mozilla::fallible_t& aFallible) { aDest.Truncate(); - if (!AppendUTF16toUTF8(aSource, aDest, mozilla::fallible_t())) { + if (!AppendUTF16toUTF8(aSource, aDest, aFallible)) { return false; } return true; @@ -108,18 +108,18 @@ LossyAppendUTF16toASCII(const nsAString& aSource, nsACString& aDest) void AppendASCIItoUTF16(const nsACString& aSource, nsAString& aDest) { - if (!AppendASCIItoUTF16(aSource, aDest, mozilla::fallible_t())) { + if (!AppendASCIItoUTF16(aSource, aDest, mozilla::fallible)) { aDest.AllocFailed(aDest.Length() + aSource.Length()); } } bool AppendASCIItoUTF16(const nsACString& aSource, nsAString& aDest, - const mozilla::fallible_t&) + const mozilla::fallible_t& aFallible) { uint32_t old_dest_length = aDest.Length(); if (!aDest.SetLength(old_dest_length + aSource.Length(), - mozilla::fallible_t())) { + aFallible)) { return false; } @@ -157,7 +157,7 @@ AppendASCIItoUTF16(const char* aSource, nsAString& aDest) void AppendUTF16toUTF8(const nsAString& aSource, nsACString& aDest) { - if (!AppendUTF16toUTF8(aSource, aDest, mozilla::fallible_t())) { + if (!AppendUTF16toUTF8(aSource, aDest, mozilla::fallible)) { // Note that this may wildly underestimate the allocation that failed, as // we report the length of aSource as UTF-16 instead of UTF-8. aDest.AllocFailed(aDest.Length() + aSource.Length()); @@ -166,7 +166,7 @@ AppendUTF16toUTF8(const nsAString& aSource, nsACString& aDest) bool AppendUTF16toUTF8(const nsAString& aSource, nsACString& aDest, - const mozilla::fallible_t&) + const mozilla::fallible_t& aFallible) { nsAString::const_iterator source_start, source_end; CalculateUTF8Size calculator; @@ -179,7 +179,7 @@ AppendUTF16toUTF8(const nsAString& aSource, nsACString& aDest, uint32_t old_dest_length = aDest.Length(); // Grow the buffer if we need to. - if (!aDest.SetLength(old_dest_length + count, mozilla::fallible_t())) { + if (!aDest.SetLength(old_dest_length + count, aFallible)) { return false; } @@ -200,14 +200,14 @@ AppendUTF16toUTF8(const nsAString& aSource, nsACString& aDest, void AppendUTF8toUTF16(const nsACString& aSource, nsAString& aDest) { - if (!AppendUTF8toUTF16(aSource, aDest, mozilla::fallible_t())) { + if (!AppendUTF8toUTF16(aSource, aDest, mozilla::fallible)) { aDest.AllocFailed(aDest.Length() + aSource.Length()); } } bool AppendUTF8toUTF16(const nsACString& aSource, nsAString& aDest, - const mozilla::fallible_t&) + const mozilla::fallible_t& aFallible) { nsACString::const_iterator source_start, source_end; CalculateUTF8Length calculator; @@ -221,7 +221,7 @@ AppendUTF8toUTF16(const nsACString& aSource, nsAString& aDest, uint32_t old_dest_length = aDest.Length(); // Grow the buffer if we need to. - if (!aDest.SetLength(old_dest_length + count, mozilla::fallible_t())) { + if (!aDest.SetLength(old_dest_length + count, aFallible)) { return false; } diff --git a/xpcom/string/nsTStringObsolete.cpp b/xpcom/string/nsTStringObsolete.cpp index fc3e790da703..df4dec296440 100644 --- a/xpcom/string/nsTStringObsolete.cpp +++ b/xpcom/string/nsTStringObsolete.cpp @@ -464,18 +464,18 @@ nsTString_CharT::ReplaceSubstring(const char_type* aTarget, bool nsTString_CharT::ReplaceSubstring(const char_type* aTarget, const char_type* aNewValue, - const fallible_t& fallible) + const fallible_t& aFallible) { return ReplaceSubstring(nsTDependentString_CharT(aTarget), nsTDependentString_CharT(aNewValue), - fallible); + aFallible); } void nsTString_CharT::ReplaceSubstring(const self_type& aTarget, const self_type& aNewValue) { - if (!ReplaceSubstring(aTarget, aNewValue, fallible_t())) { + if (!ReplaceSubstring(aTarget, aNewValue, mozilla::fallible)) { // Note that this may wildly underestimate the allocation that failed, as // we could have been replacing multiple copies of aTarget. AllocFailed(mLength + (aNewValue.Length() - aTarget.Length())); diff --git a/xpcom/string/nsTSubstring.cpp b/xpcom/string/nsTSubstring.cpp index ee1088c91095..29f36dd57c7f 100644 --- a/xpcom/string/nsTSubstring.cpp +++ b/xpcom/string/nsTSubstring.cpp @@ -253,7 +253,7 @@ nsTSubstring_CharT::EnsureMutable(size_type aNewLen) aNewLen = mLength; } - return SetLength(aNewLen, fallible_t()); + return SetLength(aNewLen, mozilla::fallible); } // --------------------------------------------------------------------------- @@ -283,7 +283,7 @@ nsTSubstring_CharT::Assign(char_type aChar, const fallible_t&) void nsTSubstring_CharT::Assign(const char_type* aData) { - if (!Assign(aData, size_type(-1), fallible_t())) { + if (!Assign(aData, size_type(-1), mozilla::fallible)) { AllocFailed(char_traits::length(aData)); } } @@ -291,7 +291,7 @@ nsTSubstring_CharT::Assign(const char_type* aData) void nsTSubstring_CharT::Assign(const char_type* aData, size_type aLength) { - if (!Assign(aData, aLength, fallible_t())) { + if (!Assign(aData, aLength, mozilla::fallible)) { AllocFailed(aLength == size_type(-1) ? char_traits::length(aData) : aLength); } @@ -299,7 +299,7 @@ nsTSubstring_CharT::Assign(const char_type* aData, size_type aLength) bool nsTSubstring_CharT::Assign(const char_type* aData, size_type aLength, - const fallible_t&) + const fallible_t& aFallible) { if (!aData || aLength == 0) { Truncate(); @@ -311,7 +311,7 @@ nsTSubstring_CharT::Assign(const char_type* aData, size_type aLength, } if (IsDependentOn(aData, aData + aLength)) { - return Assign(string_type(aData, aLength), fallible_t()); + return Assign(string_type(aData, aLength), aFallible); } if (!ReplacePrep(0, mLength, aLength)) { @@ -325,20 +325,20 @@ nsTSubstring_CharT::Assign(const char_type* aData, size_type aLength, void nsTSubstring_CharT::AssignASCII(const char* aData, size_type aLength) { - if (!AssignASCII(aData, aLength, fallible_t())) { + if (!AssignASCII(aData, aLength, mozilla::fallible)) { AllocFailed(aLength); } } bool nsTSubstring_CharT::AssignASCII(const char* aData, size_type aLength, - const fallible_t&) + const fallible_t& aFallible) { // A Unicode string can't depend on an ASCII string buffer, // so this dependence check only applies to CStrings. #ifdef CharT_is_char if (IsDependentOn(aData, aData + aLength)) { - return Assign(string_type(aData, aLength), fallible_t()); + return Assign(string_type(aData, aLength), aFallible); } #endif @@ -362,13 +362,13 @@ nsTSubstring_CharT::AssignLiteral(const char_type* aData, size_type aLength) void nsTSubstring_CharT::Assign(const self_type& aStr) { - if (!Assign(aStr, fallible_t())) { + if (!Assign(aStr, mozilla::fallible)) { AllocFailed(aStr.Length()); } } bool -nsTSubstring_CharT::Assign(const self_type& aStr, const fallible_t&) +nsTSubstring_CharT::Assign(const self_type& aStr, const fallible_t& aFallible) { // |aStr| could be sharable. We need to check its flags to know how to // deal with it. @@ -406,24 +406,24 @@ nsTSubstring_CharT::Assign(const self_type& aStr, const fallible_t&) } // else, treat this like an ordinary assignment. - return Assign(aStr.Data(), aStr.Length(), fallible_t()); + return Assign(aStr.Data(), aStr.Length(), aFallible); } void nsTSubstring_CharT::Assign(const substring_tuple_type& aTuple) { - if (!Assign(aTuple, fallible_t())) { + if (!Assign(aTuple, mozilla::fallible)) { AllocFailed(aTuple.Length()); } } bool nsTSubstring_CharT::Assign(const substring_tuple_type& aTuple, - const fallible_t&) + const fallible_t& aFallible) { if (aTuple.IsDependentOn(mData, mData + mLength)) { // take advantage of sharing here... - return Assign(string_type(aTuple), fallible_t()); + return Assign(string_type(aTuple), aFallible); } size_type length = aTuple.Length(); @@ -486,7 +486,7 @@ nsTSubstring_CharT::Replace(index_type aCutStart, size_type aCutLength, bool nsTSubstring_CharT::Replace(index_type aCutStart, size_type aCutLength, char_type aChar, - const mozilla::fallible_t&) + const fallible_t&) { aCutStart = XPCOM_MIN(aCutStart, Length()); @@ -504,7 +504,7 @@ nsTSubstring_CharT::Replace(index_type aCutStart, size_type aCutLength, const char_type* aData, size_type aLength) { if (!Replace(aCutStart, aCutLength, aData, aLength, - mozilla::fallible_t())) { + mozilla::fallible)) { AllocFailed(Length() - aCutLength + 1); } } @@ -512,7 +512,7 @@ nsTSubstring_CharT::Replace(index_type aCutStart, size_type aCutLength, bool nsTSubstring_CharT::Replace(index_type aCutStart, size_type aCutLength, const char_type* aData, size_type aLength, - const mozilla::fallible_t&) + const fallible_t& aFallible) { // unfortunately, some callers pass null :-( if (!aData) { @@ -524,7 +524,7 @@ nsTSubstring_CharT::Replace(index_type aCutStart, size_type aCutLength, if (IsDependentOn(aData, aData + aLength)) { nsTAutoString_CharT temp(aData, aLength); - return Replace(aCutStart, aCutLength, temp, mozilla::fallible_t()); + return Replace(aCutStart, aCutLength, temp, aFallible); } } @@ -602,7 +602,7 @@ nsTSubstring_CharT::ReplaceLiteral(index_type aCutStart, size_type aCutLength, void nsTSubstring_CharT::SetCapacity(size_type aCapacity) { - if (!SetCapacity(aCapacity, fallible_t())) { + if (!SetCapacity(aCapacity, mozilla::fallible)) { AllocFailed(aCapacity); } } @@ -659,9 +659,9 @@ nsTSubstring_CharT::SetLength(size_type aLength) } bool -nsTSubstring_CharT::SetLength(size_type aLength, const fallible_t&) +nsTSubstring_CharT::SetLength(size_type aLength, const fallible_t& aFallible) { - if (!SetCapacity(aLength, fallible_t())) { + if (!SetCapacity(aLength, aFallible)) { return false; } diff --git a/xpcom/string/nsTSubstring.h b/xpcom/string/nsTSubstring.h index 313bc9523eef..a967988e473d 100644 --- a/xpcom/string/nsTSubstring.h +++ b/xpcom/string/nsTSubstring.h @@ -176,9 +176,9 @@ public: return aIter = BeginWriting(); } - char_iterator& BeginWriting(char_iterator& aIter, const fallible_t&) + char_iterator& BeginWriting(char_iterator& aIter, const fallible_t& aFallible) { - return aIter = BeginWriting(fallible_t()); + return aIter = BeginWriting(aFallible); } char_iterator& EndWriting(char_iterator& aIter) @@ -186,9 +186,9 @@ public: return aIter = EndWriting(); } - char_iterator& EndWriting(char_iterator& aIter, const fallible_t&) + char_iterator& EndWriting(char_iterator& aIter, const fallible_t& aFallible) { - return aIter = EndWriting(fallible_t()); + return aIter = EndWriting(aFallible); } /** @@ -380,9 +380,10 @@ public: Assign(static_cast(aData)); } - NS_WARN_UNUSED_RESULT bool Assign(char16ptr_t aData, const fallible_t&) + NS_WARN_UNUSED_RESULT bool Assign(char16ptr_t aData, + const fallible_t& aFallible) { - return Assign(static_cast(aData), fallible_t()); + return Assign(static_cast(aData), aFallible); } void Assign(char16ptr_t aData, size_type aLength) @@ -391,9 +392,10 @@ public: } NS_WARN_UNUSED_RESULT bool Assign(char16ptr_t aData, size_type aLength, - const fallible_t&) + const fallible_t& aFallible) { - return Assign(static_cast(aData), aLength, fallible_t()); + return Assign(static_cast(aData), aLength, + aFallible); } #endif @@ -407,11 +409,11 @@ public: AssignASCII(aData, mozilla::AssertedCast(strlen(aData))); } NS_WARN_UNUSED_RESULT bool NS_FASTCALL AssignASCII(const char* aData, - const fallible_t&) + const fallible_t& aFallible) { return AssignASCII(aData, mozilla::AssertedCast(strlen(aData)), - fallible_t()); + aFallible); } // AssignLiteral must ONLY be applied to an actual literal string, or @@ -473,7 +475,7 @@ public: NS_WARN_UNUSED_RESULT bool NS_FASTCALL Replace(index_type aCutStart, size_type aCutLength, char_type aChar, - const mozilla::fallible_t&); + const fallible_t&); void NS_FASTCALL Replace(index_type aCutStart, size_type aCutLength, const char_type* aData, size_type aLength = size_type(-1)); @@ -481,7 +483,7 @@ public: size_type aCutLength, const char_type* aData, size_type aLength, - const mozilla::fallible_t&); + const fallible_t&); void Replace(index_type aCutStart, size_type aCutLength, const self_type& aStr) { @@ -490,10 +492,10 @@ public: NS_WARN_UNUSED_RESULT bool Replace(index_type aCutStart, size_type aCutLength, const self_type& aStr, - const mozilla::fallible_t&) + const fallible_t& aFallible) { return Replace(aCutStart, aCutLength, aStr.Data(), aStr.Length(), - mozilla::fallible_t()); + aFallible); } void NS_FASTCALL Replace(index_type aCutStart, size_type aCutLength, const substring_tuple_type& aTuple); @@ -517,18 +519,18 @@ public: Replace(mLength, 0, aChar); } NS_WARN_UNUSED_RESULT bool Append(char_type aChar, - const mozilla::fallible_t&) + const fallible_t& aFallible) { - return Replace(mLength, 0, aChar, mozilla::fallible_t()); + return Replace(mLength, 0, aChar, aFallible); } void Append(const char_type* aData, size_type aLength = size_type(-1)) { Replace(mLength, 0, aData, aLength); } NS_WARN_UNUSED_RESULT bool Append(const char_type* aData, size_type aLength, - const mozilla::fallible_t&) + const fallible_t& aFallible) { - return Replace(mLength, 0, aData, aLength, mozilla::fallible_t()); + return Replace(mLength, 0, aData, aLength, aFallible); } #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) @@ -766,10 +768,11 @@ public: return GetMutableData(reinterpret_cast(aData), aNewLen); } - size_type GetMutableData(wchar_t** aData, size_type aNewLen, const fallible_t&) + size_type GetMutableData(wchar_t** aData, size_type aNewLen, + const fallible_t& aFallible) { return GetMutableData(reinterpret_cast(aData), aNewLen, - fallible_t()); + aFallible); } #endif diff --git a/xpcom/tests/TestPLDHash.cpp b/xpcom/tests/TestPLDHash.cpp index 8609c3f51958..fdb6ea5bbfef 100644 --- a/xpcom/tests/TestPLDHash.cpp +++ b/xpcom/tests/TestPLDHash.cpp @@ -27,7 +27,7 @@ static bool test_pldhash_Init_capacity_ok() // will allocate 0.5GB of entry store on 32-bit platforms and 1GB on 64-bit // platforms. if (!PL_DHashTableInit(&t, PL_DHashGetStubOps(), sizeof(PLDHashEntryStub), - mozilla::fallible_t(), PL_DHASH_MAX_INITIAL_LENGTH)) { + mozilla::fallible, PL_DHASH_MAX_INITIAL_LENGTH)) { return false; } @@ -57,7 +57,7 @@ static bool test_pldhash_Init_capacity_too_large() // Try the smallest too-large capacity. if (PL_DHashTableInit(&t, PL_DHashGetStubOps(), sizeof(PLDHashEntryStub), - mozilla::fallible_t(), + mozilla::fallible, PL_DHASH_MAX_INITIAL_LENGTH + 1)) { return false; // it succeeded!? } @@ -93,7 +93,7 @@ static bool test_pldhash_Init_overflow() }; if (PL_DHashTableInit(&t, PL_DHashGetStubOps(), sizeof(OneKBEntry), - mozilla::fallible_t(), PL_DHASH_MAX_INITIAL_LENGTH)) { + mozilla::fallible, PL_DHASH_MAX_INITIAL_LENGTH)) { return false; // it succeeded!? } // Don't call PL_DHashTableFinish() here; it's not safe after Init() failure. diff --git a/xpcom/tests/gtest/TestStrings.cpp b/xpcom/tests/gtest/TestStrings.cpp index f38e868ee7e7..dc5fd6fbfb49 100644 --- a/xpcom/tests/gtest/TestStrings.cpp +++ b/xpcom/tests/gtest/TestStrings.cpp @@ -11,12 +11,11 @@ #include "nsCRTGlue.h" #include "nsRefPtr.h" #include "nsTArray.h" -#include "mozilla/fallible.h" #include "gtest/gtest.h" namespace TestStrings { -using mozilla::fallible_t; +using mozilla::fallible; void test_assign_helper(const nsACString& in, nsACString &_retval) { @@ -851,75 +850,75 @@ TEST(Strings, huge_capacity) // Ignore the result if the address space is less than 64-bit because // some of the allocations above will exhaust the address space. if (sizeof(void*) >= 8) { - EXPECT_TRUE(a.SetCapacity(1, fallible_t())); - EXPECT_FALSE(a.SetCapacity(nsString::size_type(-1)/2, fallible_t())); - EXPECT_TRUE(a.SetCapacity(0, fallible_t())); // free the allocated memory + EXPECT_TRUE(a.SetCapacity(1, fallible)); + EXPECT_FALSE(a.SetCapacity(nsString::size_type(-1)/2, fallible)); + EXPECT_TRUE(a.SetCapacity(0, fallible)); // free the allocated memory - EXPECT_TRUE(b.SetCapacity(1, fallible_t())); - EXPECT_FALSE(b.SetCapacity(nsString::size_type(-1)/2 - 1, fallible_t())); - EXPECT_TRUE(b.SetCapacity(0, fallible_t())); + EXPECT_TRUE(b.SetCapacity(1, fallible)); + EXPECT_FALSE(b.SetCapacity(nsString::size_type(-1)/2 - 1, fallible)); + EXPECT_TRUE(b.SetCapacity(0, fallible)); - EXPECT_TRUE(c.SetCapacity(1, fallible_t())); - EXPECT_FALSE(c.SetCapacity(nsString::size_type(-1)/2, fallible_t())); - EXPECT_TRUE(c.SetCapacity(0, fallible_t())); + EXPECT_TRUE(c.SetCapacity(1, fallible)); + EXPECT_FALSE(c.SetCapacity(nsString::size_type(-1)/2, fallible)); + EXPECT_TRUE(c.SetCapacity(0, fallible)); - EXPECT_FALSE(d.SetCapacity(nsString::size_type(-1)/2 - 1, fallible_t())); - EXPECT_FALSE(d.SetCapacity(nsString::size_type(-1)/2, fallible_t())); - EXPECT_TRUE(d.SetCapacity(0, fallible_t())); + EXPECT_FALSE(d.SetCapacity(nsString::size_type(-1)/2 - 1, fallible)); + EXPECT_FALSE(d.SetCapacity(nsString::size_type(-1)/2, fallible)); + EXPECT_TRUE(d.SetCapacity(0, fallible)); - EXPECT_FALSE(e.SetCapacity(nsString::size_type(-1)/4, fallible_t())); - EXPECT_FALSE(e.SetCapacity(nsString::size_type(-1)/4 + 1, fallible_t())); - EXPECT_TRUE(e.SetCapacity(0, fallible_t())); + EXPECT_FALSE(e.SetCapacity(nsString::size_type(-1)/4, fallible)); + EXPECT_FALSE(e.SetCapacity(nsString::size_type(-1)/4 + 1, fallible)); + EXPECT_TRUE(e.SetCapacity(0, fallible)); - EXPECT_FALSE(f.SetCapacity(nsString::size_type(-1)/2, fallible_t())); - EXPECT_TRUE(f.SetCapacity(0, fallible_t())); + EXPECT_FALSE(f.SetCapacity(nsString::size_type(-1)/2, fallible)); + EXPECT_TRUE(f.SetCapacity(0, fallible)); - EXPECT_FALSE(g.SetCapacity(nsString::size_type(-1)/4 + 1000, fallible_t())); - EXPECT_FALSE(g.SetCapacity(nsString::size_type(-1)/4 + 1001, fallible_t())); - EXPECT_TRUE(g.SetCapacity(0, fallible_t())); + EXPECT_FALSE(g.SetCapacity(nsString::size_type(-1)/4 + 1000, fallible)); + EXPECT_FALSE(g.SetCapacity(nsString::size_type(-1)/4 + 1001, fallible)); + EXPECT_TRUE(g.SetCapacity(0, fallible)); - EXPECT_FALSE(h.SetCapacity(nsString::size_type(-1)/4+1, fallible_t())); - EXPECT_FALSE(h.SetCapacity(nsString::size_type(-1)/2, fallible_t())); - EXPECT_TRUE(h.SetCapacity(0, fallible_t())); + EXPECT_FALSE(h.SetCapacity(nsString::size_type(-1)/4+1, fallible)); + EXPECT_FALSE(h.SetCapacity(nsString::size_type(-1)/2, fallible)); + EXPECT_TRUE(h.SetCapacity(0, fallible)); - EXPECT_TRUE(i.SetCapacity(1, fallible_t())); - EXPECT_TRUE(i.SetCapacity(nsString::size_type(-1)/4 - 1000, fallible_t())); - EXPECT_FALSE(i.SetCapacity(nsString::size_type(-1)/4 + 1, fallible_t())); - EXPECT_TRUE(i.SetCapacity(0, fallible_t())); + EXPECT_TRUE(i.SetCapacity(1, fallible)); + EXPECT_TRUE(i.SetCapacity(nsString::size_type(-1)/4 - 1000, fallible)); + EXPECT_FALSE(i.SetCapacity(nsString::size_type(-1)/4 + 1, fallible)); + EXPECT_TRUE(i.SetCapacity(0, fallible)); - EXPECT_TRUE(j.SetCapacity(nsString::size_type(-1)/4 - 1000, fallible_t())); - EXPECT_FALSE(j.SetCapacity(nsString::size_type(-1)/4 + 1, fallible_t())); - EXPECT_TRUE(j.SetCapacity(0, fallible_t())); + EXPECT_TRUE(j.SetCapacity(nsString::size_type(-1)/4 - 1000, fallible)); + EXPECT_FALSE(j.SetCapacity(nsString::size_type(-1)/4 + 1, fallible)); + EXPECT_TRUE(j.SetCapacity(0, fallible)); - EXPECT_TRUE(k.SetCapacity(nsString::size_type(-1)/8 - 1000, fallible_t())); - EXPECT_TRUE(k.SetCapacity(nsString::size_type(-1)/4 - 1001, fallible_t())); - EXPECT_TRUE(k.SetCapacity(nsString::size_type(-1)/4 - 998, fallible_t())); - EXPECT_FALSE(k.SetCapacity(nsString::size_type(-1)/4 + 1, fallible_t())); - EXPECT_TRUE(k.SetCapacity(0, fallible_t())); + EXPECT_TRUE(k.SetCapacity(nsString::size_type(-1)/8 - 1000, fallible)); + EXPECT_TRUE(k.SetCapacity(nsString::size_type(-1)/4 - 1001, fallible)); + EXPECT_TRUE(k.SetCapacity(nsString::size_type(-1)/4 - 998, fallible)); + EXPECT_FALSE(k.SetCapacity(nsString::size_type(-1)/4 + 1, fallible)); + EXPECT_TRUE(k.SetCapacity(0, fallible)); - EXPECT_TRUE(l.SetCapacity(nsString::size_type(-1)/8, fallible_t())); - EXPECT_TRUE(l.SetCapacity(nsString::size_type(-1)/8 + 1, fallible_t())); - EXPECT_TRUE(l.SetCapacity(nsString::size_type(-1)/8 + 2, fallible_t())); - EXPECT_TRUE(l.SetCapacity(0, fallible_t())); + EXPECT_TRUE(l.SetCapacity(nsString::size_type(-1)/8, fallible)); + EXPECT_TRUE(l.SetCapacity(nsString::size_type(-1)/8 + 1, fallible)); + EXPECT_TRUE(l.SetCapacity(nsString::size_type(-1)/8 + 2, fallible)); + EXPECT_TRUE(l.SetCapacity(0, fallible)); - EXPECT_TRUE(m.SetCapacity(nsString::size_type(-1)/8 + 1000, fallible_t())); - EXPECT_TRUE(m.SetCapacity(nsString::size_type(-1)/8 + 1001, fallible_t())); - EXPECT_TRUE(m.SetCapacity(0, fallible_t())); + EXPECT_TRUE(m.SetCapacity(nsString::size_type(-1)/8 + 1000, fallible)); + EXPECT_TRUE(m.SetCapacity(nsString::size_type(-1)/8 + 1001, fallible)); + EXPECT_TRUE(m.SetCapacity(0, fallible)); - EXPECT_TRUE(n.SetCapacity(nsString::size_type(-1)/8+1, fallible_t())); - EXPECT_FALSE(n.SetCapacity(nsString::size_type(-1)/4, fallible_t())); - EXPECT_TRUE(n.SetCapacity(0, fallible_t())); + EXPECT_TRUE(n.SetCapacity(nsString::size_type(-1)/8+1, fallible)); + EXPECT_FALSE(n.SetCapacity(nsString::size_type(-1)/4, fallible)); + EXPECT_TRUE(n.SetCapacity(0, fallible)); - EXPECT_TRUE(n.SetCapacity(0, fallible_t())); - EXPECT_TRUE(n.SetCapacity((nsString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 2 - 2, fallible_t())); - EXPECT_TRUE(n.SetCapacity(0, fallible_t())); - EXPECT_FALSE(n.SetCapacity((nsString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 2 - 1, fallible_t())); - EXPECT_TRUE(n.SetCapacity(0, fallible_t())); - EXPECT_TRUE(n1.SetCapacity(0, fallible_t())); - EXPECT_TRUE(n1.SetCapacity((nsCString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 1 - 2, fallible_t())); - EXPECT_TRUE(n1.SetCapacity(0, fallible_t())); - EXPECT_FALSE(n1.SetCapacity((nsCString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 1 - 1, fallible_t())); - EXPECT_TRUE(n1.SetCapacity(0, fallible_t())); + EXPECT_TRUE(n.SetCapacity(0, fallible)); + EXPECT_TRUE(n.SetCapacity((nsString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 2 - 2, fallible)); + EXPECT_TRUE(n.SetCapacity(0, fallible)); + EXPECT_FALSE(n.SetCapacity((nsString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 2 - 1, fallible)); + EXPECT_TRUE(n.SetCapacity(0, fallible)); + EXPECT_TRUE(n1.SetCapacity(0, fallible)); + EXPECT_TRUE(n1.SetCapacity((nsCString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 1 - 2, fallible)); + EXPECT_TRUE(n1.SetCapacity(0, fallible)); + EXPECT_FALSE(n1.SetCapacity((nsCString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 1 - 1, fallible)); + EXPECT_TRUE(n1.SetCapacity(0, fallible)); } } From f36ab0e55f7d074f3006ce7193d6bc60e6c581a2 Mon Sep 17 00:00:00 2001 From: Georg Fritzsche Date: Thu, 29 Jan 2015 15:17:24 +0100 Subject: [PATCH 10/16] Bug 1120369 - Allow specifying the desired dataset in Histograms.json. r=vladan --- toolkit/components/telemetry/Histograms.json | 26 + toolkit/components/telemetry/Telemetry.cpp | 458 +++++++++++------- .../components/telemetry/TelemetrySession.jsm | 6 +- .../telemetry/gen-histogram-data.py | 4 +- .../components/telemetry/histogram_tools.py | 13 +- toolkit/components/telemetry/nsITelemetry.idl | 21 +- .../tests/unit/test_TelemetryPing.js | 2 +- .../telemetry/tests/unit/test_nsITelemetry.js | 50 +- 8 files changed, 384 insertions(+), 196 deletions(-) diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 4ebccbc4c85e..8c74abb2c675 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -4336,6 +4336,32 @@ "keyed": true, "description": "a testing histogram; not meant to be touched" }, + "TELEMETRY_TEST_RELEASE_OPTOUT": { + "expires_in_version": "default", + "kind": "flag", + "releaseChannelCollection": "opt-out", + "description": "a testing histogram; not meant to be touched" + }, + "TELEMETRY_TEST_RELEASE_OPTIN": { + "expires_in_version": "default", + "kind": "flag", + "releaseChannelCollection": "opt-in", + "description": "a testing histogram; not meant to be touched" + }, + "TELEMETRY_TEST_KEYED_RELEASE_OPTIN": { + "expires_in_version": "default", + "kind": "flag", + "keyed": true, + "releaseChannelCollection": "opt-in", + "description": "a testing histogram; not meant to be touched" + }, + "TELEMETRY_TEST_KEYED_RELEASE_OPTOUT": { + "expires_in_version": "default", + "kind": "flag", + "keyed": true, + "releaseChannelCollection": "opt-out", + "description": "a testing histogram; not meant to be touched" + }, "STARTUP_CRASH_DETECTED": { "expires_in_version": "never", "kind": "flag", diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/Telemetry.cpp index a1c03008b9c6..efda666f9698 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -626,184 +626,7 @@ ClearIOReporting() sTelemetryIOObserver = nullptr; } -class KeyedHistogram { -public: - KeyedHistogram(const nsACString &name, const nsACString &expiration, - uint32_t histogramType, uint32_t min, uint32_t max, - uint32_t bucketCount); - nsresult GetHistogram(const nsCString& name, Histogram** histogram); - Histogram* GetHistogram(const nsCString& name); - uint32_t GetHistogramType() const { return mHistogramType; } - nsresult GetJSKeys(JSContext* cx, JS::CallArgs& args); - nsresult GetJSSnapshot(JSContext* cx, JS::Handle obj); - void Clear(); - -private: - typedef nsBaseHashtableET KeyedHistogramEntry; - typedef AutoHashtable KeyedHistogramMapType; - KeyedHistogramMapType mHistogramMap; - - struct ReflectKeysArgs { - JSContext* jsContext; - JS::AutoValueVector* vector; - }; - static PLDHashOperator ReflectKeys(KeyedHistogramEntry* entry, void* arg); - - static bool ReflectKeyedHistogram(KeyedHistogramEntry* entry, - JSContext* cx, - JS::Handle obj); - - static PLDHashOperator ClearHistogramEnumerator(KeyedHistogramEntry*, void*); - - const nsCString mName; - const nsCString mExpiration; - const uint32_t mHistogramType; - const uint32_t mMin; - const uint32_t mMax; - const uint32_t mBucketCount; -}; - -KeyedHistogram::KeyedHistogram(const nsACString &name, const nsACString &expiration, - uint32_t histogramType, uint32_t min, uint32_t max, - uint32_t bucketCount) - : mHistogramMap() - , mName(name) - , mExpiration(expiration) - , mHistogramType(histogramType) - , mMin(min) - , mMax(max) - , mBucketCount(bucketCount) -{ -} - -nsresult -KeyedHistogram::GetHistogram(const nsCString& key, Histogram** histogram) -{ - KeyedHistogramEntry* entry = mHistogramMap.GetEntry(key); - if (entry) { - *histogram = entry->mData; - return NS_OK; - } - - nsCString histogramName = mName; - histogramName.Append(KEYED_HISTOGRAM_NAME_SEPARATOR); - histogramName.Append(key); - - Histogram* h; - nsresult rv = HistogramGet(histogramName.get(), mExpiration.get(), - mHistogramType, mMin, mMax, mBucketCount, - true, &h); - if (NS_FAILED(rv)) { - return rv; - } - - h->ClearFlags(Histogram::kUmaTargetedHistogramFlag); - h->SetFlags(Histogram::kExtendedStatisticsFlag); - *histogram = h; - - entry = mHistogramMap.PutEntry(key); - if (MOZ_UNLIKELY(!entry)) { - return NS_ERROR_OUT_OF_MEMORY; - } - - entry->mData = h; - return NS_OK; -} - -Histogram* -KeyedHistogram::GetHistogram(const nsCString& key) -{ - Histogram* h = nullptr; - if (NS_FAILED(GetHistogram(key, &h))) { - return nullptr; - } - return h; -} - -/* static */ -PLDHashOperator -KeyedHistogram::ClearHistogramEnumerator(KeyedHistogramEntry* entry, void*) -{ - entry->mData->Clear(); - return PL_DHASH_NEXT; -} - -void -KeyedHistogram::Clear() -{ - mHistogramMap.EnumerateEntries(&KeyedHistogram::ClearHistogramEnumerator, nullptr); - mHistogramMap.Clear(); -} - -/* static */ -PLDHashOperator -KeyedHistogram::ReflectKeys(KeyedHistogramEntry* entry, void* arg) -{ - ReflectKeysArgs* args = static_cast(arg); - - JS::RootedValue jsKey(args->jsContext); - const NS_ConvertUTF8toUTF16 key(entry->GetKey()); - jsKey.setString(JS_NewUCStringCopyN(args->jsContext, key.Data(), key.Length())); - args->vector->append(jsKey); - - return PL_DHASH_NEXT; -} - -nsresult -KeyedHistogram::GetJSKeys(JSContext* cx, JS::CallArgs& args) -{ - JS::AutoValueVector keys(cx); - if (!keys.reserve(mHistogramMap.Count())) { - return NS_ERROR_OUT_OF_MEMORY; - } - - ReflectKeysArgs reflectArgs = { cx, &keys }; - const uint32_t num = mHistogramMap.EnumerateEntries(&KeyedHistogram::ReflectKeys, - static_cast(&reflectArgs)); - if (num != mHistogramMap.Count()) { - return NS_ERROR_FAILURE; - } - - JS::RootedObject jsKeys(cx, JS_NewArrayObject(cx, keys)); - if (!jsKeys) { - return NS_ERROR_FAILURE; - } - - args.rval().setObject(*jsKeys); - return NS_OK; -} - -/* static */ -bool -KeyedHistogram::ReflectKeyedHistogram(KeyedHistogramEntry* entry, JSContext* cx, JS::Handle obj) -{ - JS::RootedObject histogramSnapshot(cx, JS_NewPlainObject(cx)); - if (!histogramSnapshot) { - return false; - } - - if (ReflectHistogramSnapshot(cx, histogramSnapshot, entry->mData) != REFLECT_OK) { - return false; - } - - const NS_ConvertUTF8toUTF16 key(entry->GetKey()); - if (!JS_DefineUCProperty(cx, obj, key.Data(), key.Length(), - histogramSnapshot, JSPROP_ENUMERATE)) { - return false; - } - - return true; -} - -nsresult -KeyedHistogram::GetJSSnapshot(JSContext* cx, JS::Handle obj) -{ - if (!mHistogramMap.ReflectIntoJS(&KeyedHistogram::ReflectKeyedHistogram, cx, obj)) { - return NS_ERROR_FAILURE; - } - - return NS_OK; -} +class KeyedHistogram; class TelemetryImpl MOZ_FINAL : public nsITelemetry @@ -940,6 +763,44 @@ TelemetryImpl::CollectReports(nsIHandleReportCallback* aHandleReport, "Memory used by the telemetry system."); } +class KeyedHistogram { +public: + KeyedHistogram(const nsACString &name, const nsACString &expiration, + uint32_t histogramType, uint32_t min, uint32_t max, + uint32_t bucketCount); + nsresult GetHistogram(const nsCString& name, Histogram** histogram); + Histogram* GetHistogram(const nsCString& name); + uint32_t GetHistogramType() const { return mHistogramType; } + nsresult GetDataset(uint32_t* dataset) const; + nsresult GetJSKeys(JSContext* cx, JS::CallArgs& args); + nsresult GetJSSnapshot(JSContext* cx, JS::Handle obj); + void Clear(); + +private: + typedef nsBaseHashtableET KeyedHistogramEntry; + typedef AutoHashtable KeyedHistogramMapType; + KeyedHistogramMapType mHistogramMap; + + struct ReflectKeysArgs { + JSContext* jsContext; + JS::AutoValueVector* vector; + }; + static PLDHashOperator ReflectKeys(KeyedHistogramEntry* entry, void* arg); + + static bool ReflectKeyedHistogram(KeyedHistogramEntry* entry, + JSContext* cx, + JS::Handle obj); + + static PLDHashOperator ClearHistogramEnumerator(KeyedHistogramEntry*, void*); + + const nsCString mName; + const nsCString mExpiration; + const uint32_t mHistogramType; + const uint32_t mMin; + const uint32_t mMax; + const uint32_t mBucketCount; +}; + // A initializer to initialize histogram collection StatisticsRecorder gStatisticsRecorder; @@ -951,6 +812,7 @@ struct TelemetryHistogram { uint32_t histogramType; uint32_t id_offset; uint32_t expiration_offset; + uint32_t dataset; bool extendedStatisticsOK; bool keyed; @@ -992,6 +854,23 @@ IsValidHistogramName(const nsACString& name) return !FindInReadable(nsCString(KEYED_HISTOGRAM_NAME_SEPARATOR), name); } +bool +IsInDataset(const TelemetryHistogram& h, uint32_t dataset) +{ + if (h.dataset == dataset) { + return true; + } + + // The "optin on release channel" dataset is a superset of the + // "optout on release channel one". + if (dataset == nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN + && h.dataset == nsITelemetry::DATASET_RELEASE_CHANNEL_OPTOUT) { + return true; + } + + return false; +} + nsresult CheckHistogramArguments(uint32_t histogramType, uint32_t min, uint32_t max, uint32_t bucketCount, bool haveOptArgs) @@ -1272,6 +1151,26 @@ JSHistogram_Clear(JSContext *cx, unsigned argc, JS::Value *vp) return true; } +bool +JSHistogram_Dataset(JSContext *cx, unsigned argc, JS::Value *vp) +{ + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + JSObject *obj = JS_THIS_OBJECT(cx, vp); + if (!obj) { + return false; + } + + Histogram *h = static_cast(JS_GetPrivate(obj)); + Telemetry::ID id; + nsresult rv = TelemetryImpl::GetHistogramEnumId(h->histogram_name().c_str(), &id); + if (NS_SUCCEEDED(rv)) { + args.rval().setNumber(gHistograms[id].dataset); + return true; + } + + return false; +} + nsresult WrapAndReturnHistogram(Histogram *h, JSContext *cx, JS::MutableHandle ret) { @@ -1285,7 +1184,8 @@ WrapAndReturnHistogram(Histogram *h, JSContext *cx, JS::MutableHandle return NS_ERROR_FAILURE; if (!(JS_DefineFunction(cx, obj, "add", JSHistogram_Add, 1, 0) && JS_DefineFunction(cx, obj, "snapshot", JSHistogram_Snapshot, 0, 0) - && JS_DefineFunction(cx, obj, "clear", JSHistogram_Clear, 0, 0))) { + && JS_DefineFunction(cx, obj, "clear", JSHistogram_Clear, 0, 0) + && JS_DefineFunction(cx, obj, "dataset", JSHistogram_Dataset, 0, 0))) { return NS_ERROR_FAILURE; } JS_SetPrivate(obj, h); @@ -1448,6 +1348,30 @@ JSKeyedHistogram_Clear(JSContext *cx, unsigned argc, JS::Value *vp) return true; } +bool +JSKeyedHistogram_Dataset(JSContext *cx, unsigned argc, JS::Value *vp) +{ + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + JSObject *obj = JS_THIS_OBJECT(cx, vp); + if (!obj) { + return false; + } + + KeyedHistogram* keyed = static_cast(JS_GetPrivate(obj)); + if (!keyed) { + return false; + } + + uint32_t dataset = nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN; + nsresult rv = keyed->GetDataset(&dataset);; + if (NS_FAILED(rv)) { + return false; + } + + args.rval().setNumber(dataset); + return true; +} + nsresult WrapAndReturnKeyedHistogram(KeyedHistogram *h, JSContext *cx, JS::MutableHandle ret) { @@ -1462,7 +1386,8 @@ WrapAndReturnKeyedHistogram(KeyedHistogram *h, JSContext *cx, JS::MutableHandle< if (!(JS_DefineFunction(cx, obj, "add", JSKeyedHistogram_Add, 2, 0) && JS_DefineFunction(cx, obj, "snapshot", JSKeyedHistogram_Snapshot, 1, 0) && JS_DefineFunction(cx, obj, "keys", JSKeyedHistogram_Keys, 0, 0) - && JS_DefineFunction(cx, obj, "clear", JSKeyedHistogram_Clear, 0, 0))) { + && JS_DefineFunction(cx, obj, "clear", JSKeyedHistogram_Clear, 0, 0) + && JS_DefineFunction(cx, obj, "dataset", JSKeyedHistogram_Dataset, 0, 0))) { return NS_ERROR_FAILURE; } @@ -2887,13 +2812,15 @@ TelemetryImpl::GetLateWrites(JSContext *cx, JS::MutableHandle ret) } nsresult -GetRegisteredHistogramIds(bool keyed, uint32_t *aCount, char*** aHistograms) +GetRegisteredHistogramIds(bool keyed, uint32_t dataset, uint32_t *aCount, + char*** aHistograms) { nsTArray collection; for (size_t i = 0; i < ArrayLength(gHistograms); ++i) { const TelemetryHistogram& h = gHistograms[i]; - if (IsExpired(h.expiration()) || h.keyed != keyed) { + if (IsExpired(h.expiration()) || h.keyed != keyed || + !IsInDataset(h, dataset)) { continue; } @@ -2912,15 +2839,17 @@ GetRegisteredHistogramIds(bool keyed, uint32_t *aCount, char*** aHistograms) } NS_IMETHODIMP -TelemetryImpl::RegisteredHistograms(uint32_t *aCount, char*** aHistograms) +TelemetryImpl::RegisteredHistograms(uint32_t aDataset, uint32_t *aCount, + char*** aHistograms) { - return GetRegisteredHistogramIds(false, aCount, aHistograms); + return GetRegisteredHistogramIds(false, aDataset, aCount, aHistograms); } NS_IMETHODIMP -TelemetryImpl::RegisteredKeyedHistograms(uint32_t *aCount, char*** aHistograms) +TelemetryImpl::RegisteredKeyedHistograms(uint32_t aDataset, uint32_t *aCount, + char*** aHistograms) { - return GetRegisteredHistogramIds(true, aCount, aHistograms); + return GetRegisteredHistogramIds(true, aDataset, aCount, aHistograms); } NS_IMETHODIMP @@ -3836,3 +3765,160 @@ XRE_TelemetryAccumulate(int aID, uint32_t aSample) { mozilla::Telemetry::Accumulate((mozilla::Telemetry::ID) aID, aSample); } + +KeyedHistogram::KeyedHistogram(const nsACString &name, const nsACString &expiration, + uint32_t histogramType, uint32_t min, uint32_t max, + uint32_t bucketCount) + : mHistogramMap() + , mName(name) + , mExpiration(expiration) + , mHistogramType(histogramType) + , mMin(min) + , mMax(max) + , mBucketCount(bucketCount) +{ +} + +nsresult +KeyedHistogram::GetHistogram(const nsCString& key, Histogram** histogram) +{ + KeyedHistogramEntry* entry = mHistogramMap.GetEntry(key); + if (entry) { + *histogram = entry->mData; + return NS_OK; + } + + nsCString histogramName = mName; + histogramName.Append(KEYED_HISTOGRAM_NAME_SEPARATOR); + histogramName.Append(key); + + Histogram* h; + nsresult rv = HistogramGet(histogramName.get(), mExpiration.get(), + mHistogramType, mMin, mMax, mBucketCount, + true, &h); + if (NS_FAILED(rv)) { + return rv; + } + + h->ClearFlags(Histogram::kUmaTargetedHistogramFlag); + h->SetFlags(Histogram::kExtendedStatisticsFlag); + *histogram = h; + + entry = mHistogramMap.PutEntry(key); + if (MOZ_UNLIKELY(!entry)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + entry->mData = h; + return NS_OK; +} + +Histogram* +KeyedHistogram::GetHistogram(const nsCString& key) +{ + Histogram* h = nullptr; + if (NS_FAILED(GetHistogram(key, &h))) { + return nullptr; + } + return h; +} + +nsresult +KeyedHistogram::GetDataset(uint32_t* dataset) const +{ + MOZ_ASSERT(dataset); + + Telemetry::ID id; + nsresult rv = TelemetryImpl::GetHistogramEnumId(mName.get(), &id); + if (NS_FAILED(rv)) { + return rv; + } + + *dataset = gHistograms[id].dataset; + return NS_OK; +} + +/* static */ +PLDHashOperator +KeyedHistogram::ClearHistogramEnumerator(KeyedHistogramEntry* entry, void*) +{ + entry->mData->Clear(); + return PL_DHASH_NEXT; +} + +void +KeyedHistogram::Clear() +{ + mHistogramMap.EnumerateEntries(&KeyedHistogram::ClearHistogramEnumerator, nullptr); + mHistogramMap.Clear(); +} + +/* static */ +PLDHashOperator +KeyedHistogram::ReflectKeys(KeyedHistogramEntry* entry, void* arg) +{ + ReflectKeysArgs* args = static_cast(arg); + + JS::RootedValue jsKey(args->jsContext); + const NS_ConvertUTF8toUTF16 key(entry->GetKey()); + jsKey.setString(JS_NewUCStringCopyN(args->jsContext, key.Data(), key.Length())); + args->vector->append(jsKey); + + return PL_DHASH_NEXT; +} + +nsresult +KeyedHistogram::GetJSKeys(JSContext* cx, JS::CallArgs& args) +{ + JS::AutoValueVector keys(cx); + if (!keys.reserve(mHistogramMap.Count())) { + return NS_ERROR_OUT_OF_MEMORY; + } + + ReflectKeysArgs reflectArgs = { cx, &keys }; + const uint32_t num = mHistogramMap.EnumerateEntries(&KeyedHistogram::ReflectKeys, + static_cast(&reflectArgs)); + if (num != mHistogramMap.Count()) { + return NS_ERROR_FAILURE; + } + + JS::RootedObject jsKeys(cx, JS_NewArrayObject(cx, keys)); + if (!jsKeys) { + return NS_ERROR_FAILURE; + } + + args.rval().setObject(*jsKeys); + return NS_OK; +} + +/* static */ +bool +KeyedHistogram::ReflectKeyedHistogram(KeyedHistogramEntry* entry, JSContext* cx, JS::Handle obj) +{ + JS::RootedObject histogramSnapshot(cx, JS_NewPlainObject(cx)); + if (!histogramSnapshot) { + return false; + } + + if (ReflectHistogramSnapshot(cx, histogramSnapshot, entry->mData) != REFLECT_OK) { + return false; + } + + const NS_ConvertUTF8toUTF16 key(entry->GetKey()); + if (!JS_DefineUCProperty(cx, obj, key.Data(), key.Length(), + histogramSnapshot, JSPROP_ENUMERATE)) { + return false; + } + + return true; +} + +nsresult +KeyedHistogram::GetJSSnapshot(JSContext* cx, JS::Handle obj) +{ + if (!mHistogramMap.ReflectIntoJS(&KeyedHistogram::ReflectKeyedHistogram, cx, obj)) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} diff --git a/toolkit/components/telemetry/TelemetrySession.jsm b/toolkit/components/telemetry/TelemetrySession.jsm index ecf42c7945f9..06859d6ffbf4 100644 --- a/toolkit/components/telemetry/TelemetrySession.jsm +++ b/toolkit/components/telemetry/TelemetrySession.jsm @@ -460,7 +460,7 @@ let Impl = { getHistograms: function getHistograms(hls) { this._log.trace("getHistograms"); - let registered = Telemetry.registeredHistograms([]); + let registered = Telemetry.registeredHistograms(Ci.nsITelemetry.DATASET_EXTENDED, []); let ret = {}; for (let name of registered) { @@ -496,7 +496,7 @@ let Impl = { getKeyedHistograms: function() { this._log.trace("getKeyedHistograms"); - let registered = Telemetry.registeredKeyedHistograms([]); + let registered = Telemetry.registeredKeyedHistograms(Ci.nsITelemetry.DATASET_EXTENDED, []); let ret = {}; for (let id of registered) { @@ -771,7 +771,7 @@ let Impl = { gatherStartupHistograms: function gatherStartupHistograms() { this._log.trace("gatherStartupHistograms"); - let info = Telemetry.registeredHistograms([]); + let info = Telemetry.registeredHistograms(Ci.nsITelemetry.DATASET_EXTENDED, []); let snapshots = Telemetry.histogramSnapshots; for (let name of info) { // Only duplicate histograms with actual data. diff --git a/toolkit/components/telemetry/gen-histogram-data.py b/toolkit/components/telemetry/gen-histogram-data.py index e5de440cfb6a..5b6a108511a4 100644 --- a/toolkit/components/telemetry/gen-histogram-data.py +++ b/toolkit/components/telemetry/gen-histogram-data.py @@ -60,10 +60,10 @@ def print_array_entry(histogram, name_index, exp_index): cpp_guard = histogram.cpp_guard() if cpp_guard: print "#if defined(%s)" % cpp_guard - print " { %s, %s, %s, %s, %d, %d, %s, %s }," \ + print " { %s, %s, %s, %s, %d, %d, %s, %s, %s }," \ % (histogram.low(), histogram.high(), histogram.n_buckets(), histogram.nsITelemetry_kind(), - name_index, exp_index, + name_index, exp_index, histogram.dataset(), "true" if histogram.extended_statistics_ok() else "false", "true" if histogram.keyed() else "false") if cpp_guard: diff --git a/toolkit/components/telemetry/histogram_tools.py b/toolkit/components/telemetry/histogram_tools.py index 19d3abf63b54..aa9a2318a1b6 100644 --- a/toolkit/components/telemetry/histogram_tools.py +++ b/toolkit/components/telemetry/histogram_tools.py @@ -55,7 +55,8 @@ def exponential_buckets(dmin, dmax, n_buckets): ret_array[bucket_index] = current return ret_array -always_allowed_keys = ['kind', 'description', 'cpp_guard', 'expires_in_version', "alert_emails", 'keyed'] +always_allowed_keys = ['kind', 'description', 'cpp_guard', 'expires_in_version', + 'alert_emails', 'keyed', 'releaseChannelCollection'] class Histogram: """A class for representing a histogram definition.""" @@ -88,6 +89,12 @@ symbol that should guard C/C++ definitions associated with the histogram.""" 'exponential': 'EXPONENTIAL' } table_dispatch(self.kind(), table, lambda k: self._set_nsITelemetry_kind(k)) + datasets = { 'opt-in': 'DATASET_RELEASE_CHANNEL_OPTIN', + 'opt-out': 'DATASET_RELEASE_CHANNEL_OPTOUT' } + value = definition.get('releaseChannelCollection', 'opt-in') + if not value in datasets: + raise DefinitionException, "unknown release channel collection policy for " + name + self._dataset = "nsITelemetry::" + datasets[value] def name(self): """Return the name of the histogram.""" @@ -135,6 +142,10 @@ associated with the histogram. Returns None if no guarding is necessary.""" """Returns True if this a keyed histogram, false otherwise.""" return self._keyed + def dataset(self): + """Returns the dataset this histogram belongs into.""" + return self._dataset + def extended_statistics_ok(self): """Return True if gathering extended statistics for this histogram is enabled.""" diff --git a/toolkit/components/telemetry/nsITelemetry.idl b/toolkit/components/telemetry/nsITelemetry.idl index b84f19b9017e..dc1de46b4fba 100644 --- a/toolkit/components/telemetry/nsITelemetry.idl +++ b/toolkit/components/telemetry/nsITelemetry.idl @@ -29,6 +29,16 @@ interface nsITelemetry : nsISupports const unsigned long HISTOGRAM_FLAG = 3; const unsigned long HISTOGRAM_COUNT = 4; + /** + * Dataset types: + * DATASET_RELEASE_CHANNEL_OPTOUT - the basic dataset that is on-by-default on all channels + * DATASET_RELEASE_CHANNEL_OPTIN - the extended dataset that is opt-in on release, + * opt-out on pre-release channels. + */ + const unsigned long DATASET_RELEASE_CHANNEL_OPTOUT = 0; + const unsigned long DATASET_RELEASE_CHANNEL_OPTIN = 1; + + /* * An object containing a snapshot from all of the currently registered histograms. * { name1: {data1}, name2:{data2}...} @@ -134,8 +144,11 @@ interface nsITelemetry : nsISupports /** * Returns an array whose values are the names of histograms defined * in Histograms.json. + * + * @param dataset - DATASET_RELEASE_CHANNEL_OPTOUT or DATASET_RELEASE_CHANNEL_OPTIN */ - void registeredHistograms(out uint32_t count, + void registeredHistograms(in uint32_t dataset, + out uint32_t count, [retval, array, size_is(count)] out string histograms); /** @@ -151,6 +164,7 @@ interface nsITelemetry : nsISupports * add(int) - Adds an int value to the appropriate bucket * snapshot() - Returns a snapshot of the histogram with the same data fields as in histogramSnapshots() * clear() - Zeros out the histogram's buckets and sum + * dataset() - identifies what dataset this is in: DATASET_RELEASE_CHANNEL_OPTOUT or ...OPTIN */ [implicit_jscontext, optional_argc] jsval newHistogram(in ACString name, in ACString expiration, @@ -200,6 +214,7 @@ interface nsITelemetry : nsISupports * snapshot([optional] string key) - If key is provided, returns a snapshot for the histogram with that key or null. If key is not provided, returns the snapshots of all the registered keys in the form {key1: snapshot1, key2: snapshot2, ...}. * keys() - Returns an array with the string keys of the currently registered histograms * clear() - Clears the registered histograms from this. + * dataset() - identifies what dataset this is in: DATASET_RELEASE_CHANNEL_OPTOUT or ...OPTIN */ [implicit_jscontext, optional_argc] jsval newKeyedHistogram(in ACString name, @@ -212,8 +227,10 @@ interface nsITelemetry : nsISupports /** * Returns an array whose values are the names of histograms defined * in Histograms.json. + * + * @param dataset - DATASET_RELEASE_CHANNEL_OPTOUT or ...OPTIN */ - void registeredKeyedHistograms(out uint32_t count, + void registeredKeyedHistograms(in uint32_t dataset, out uint32_t count, [retval, array, size_is(count)] out string histograms); /** diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js index 12e48b7aabe2..b5c6543d2008 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js +++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js @@ -259,7 +259,7 @@ function checkPayload(request, reason, successfulPings) { do_check_true(TELEMETRY_TEST_FLAG in payload.histograms); do_check_true(TELEMETRY_TEST_COUNT in payload.histograms); - let rh = Telemetry.registeredHistograms([]); + let rh = Telemetry.registeredHistograms(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, []); for (let name of rh) { if (/SQLITE/.test(name) && name in payload.histograms) { do_check_true(("STARTUP_" + name) in payload.histograms); diff --git a/toolkit/components/telemetry/tests/unit/test_nsITelemetry.js b/toolkit/components/telemetry/tests/unit/test_nsITelemetry.js index 6511c3279a45..d0d1ecf7337c 100644 --- a/toolkit/components/telemetry/tests/unit/test_nsITelemetry.js +++ b/toolkit/components/telemetry/tests/unit/test_nsITelemetry.js @@ -15,7 +15,8 @@ function test_expired_histogram() { var clone_id = "ExpiredClone"; var dummy = Telemetry.newHistogram(histogram_id, "28.0a1", Telemetry.HISTOGRAM_EXPONENTIAL, 1, 2, 3); var dummy_clone = Telemetry.histogramFrom(clone_id, test_expired_id); - var rh = Telemetry.registeredHistograms([]); + var rh = Telemetry.registeredHistograms(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, []); + Assert.ok(!!rh); dummy.add(1); dummy_clone.add(1); @@ -558,6 +559,52 @@ function test_keyed_histogram() { test_keyed_flag_histogram(); } +function test_datasets() +{ + // Check that datasets work as expected. + + const RELEASE_CHANNEL_OPTOUT = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT; + const RELEASE_CHANNEL_OPTIN = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN; + + // Histograms should default to the extended dataset + let h = Telemetry.getHistogramById("TELEMETRY_TEST_FLAG"); + Assert.equal(h.dataset(), RELEASE_CHANNEL_OPTIN); + h = Telemetry.getKeyedHistogramById("TELEMETRY_TEST_KEYED_FLAG"); + Assert.equal(h.dataset(), RELEASE_CHANNEL_OPTIN); + + // Check test histograms with explicit dataset definitions + h = Telemetry.getHistogramById("TELEMETRY_TEST_RELEASE_OPTIN"); + Assert.equal(h.dataset(), RELEASE_CHANNEL_OPTIN); + h = Telemetry.getHistogramById("TELEMETRY_TEST_RELEASE_OPTOUT"); + Assert.equal(h.dataset(), RELEASE_CHANNEL_OPTOUT); + h = Telemetry.getKeyedHistogramById("TELEMETRY_TEST_KEYED_RELEASE_OPTIN"); + Assert.equal(h.dataset(), RELEASE_CHANNEL_OPTIN); + h = Telemetry.getKeyedHistogramById("TELEMETRY_TEST_KEYED_RELEASE_OPTOUT"); + Assert.equal(h.dataset(), RELEASE_CHANNEL_OPTOUT); + + // Check that registeredHistogram works properly + let registered = Telemetry.registeredHistograms(RELEASE_CHANNEL_OPTIN, []); + registered = new Set(registered); + Assert.ok(registered.has("TELEMETRY_TEST_FLAG")); + Assert.ok(registered.has("TELEMETRY_TEST_RELEASE_OPTIN")); + Assert.ok(registered.has("TELEMETRY_TEST_RELEASE_OPTOUT")); + registered = Telemetry.registeredHistograms(RELEASE_CHANNEL_OPTOUT, []); + registered = new Set(registered); + Assert.ok(!registered.has("TELEMETRY_TEST_FLAG")); + Assert.ok(!registered.has("TELEMETRY_TEST_RELEASE_OPTIN")); + Assert.ok(registered.has("TELEMETRY_TEST_RELEASE_OPTOUT")); + + // Check that registeredKeyedHistograms works properly + registered = Telemetry.registeredKeyedHistograms(RELEASE_CHANNEL_OPTIN, []); + registered = new Set(registered); + Assert.ok(registered.has("TELEMETRY_TEST_KEYED_FLAG")); + Assert.ok(registered.has("TELEMETRY_TEST_KEYED_RELEASE_OPTOUT")); + registered = Telemetry.registeredKeyedHistograms(RELEASE_CHANNEL_OPTOUT, []); + registered = new Set(registered); + Assert.ok(!registered.has("TELEMETRY_TEST_KEYED_FLAG")); + Assert.ok(registered.has("TELEMETRY_TEST_KEYED_RELEASE_OPTOUT")); +} + function generateUUID() { let str = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString(); // strip {} @@ -592,4 +639,5 @@ function run_test() test_extended_stats(); test_expired_histogram(); test_keyed_histogram(); + test_datasets(); } From 33f9c446a1c2da847ef7ccedf0719f4399c99ce3 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Mon, 12 Jan 2015 18:13:18 -0500 Subject: [PATCH 11/16] Bug 950934 - Enable APZ in the B2G root process. r=botond,smaug --- docshell/base/nsDocShell.cpp | 2 +- layout/base/nsLayoutUtils.cpp | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 55073f89d01e..5b4eb5be8dfa 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -13680,7 +13680,7 @@ nsDocShell::GetAsyncPanZoomEnabled(bool* aOut) *aOut = tabChild->IsAsyncPanZoomEnabled(); return NS_OK; } - *aOut = false; + *aOut = Preferences::GetBool("layers.async-pan-zoom.enabled", false); return NS_OK; } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 47812759ce52..225383be1414 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -7647,15 +7647,8 @@ nsLayoutUtils::CalculateExpandedScrollableRect(nsIFrame* aFrame) /* static */ bool nsLayoutUtils::WantSubAPZC() { - // TODO Turn this on for inprocess OMTC on all platforms - bool wantSubAPZC = gfxPrefs::AsyncPanZoomEnabled() && - gfxPrefs::APZSubframeEnabled(); -#ifdef MOZ_WIDGET_GONK - if (XRE_GetProcessType() != GeckoProcessType_Content) { - wantSubAPZC = false; - } -#endif - return wantSubAPZC; + return gfxPrefs::AsyncPanZoomEnabled() && + gfxPrefs::APZSubframeEnabled(); } /* static */ bool From 0d36926e5344c50ef02d71e25b2704d31d83e229 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 14 Jan 2015 18:05:46 -0500 Subject: [PATCH 12/16] Bug 950934 - Do not generate mouse events from touch events at the gonk widget layer. r=kats --- widget/gonk/nsWindow.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index 732d3a33e7a5..4977500e2fdd 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -281,23 +281,6 @@ nsWindow::DispatchTouchInputViaAPZ(MultiTouchInput& aInput) // but if it doesn't we need to notify the APZ of various things. All of // that happens in DispatchEventForAPZ rv = DispatchEventForAPZ(&event, guid, inputBlockId); - - // Finally, if the touch event had only one touch point, generate a mouse - // event for it and send it through the gecko root process. - // Technically we should not need to do this if the touch event was routed - // to the child process, but that seems to expose a bug in B2G where the - // keyboard doesn't go away in some cases. - // Also for now we're dispatching mouse events from all touch events because - // we need this for click events to work in the chrome process. Once we have - // APZ and ChromeProcessController::HandleSingleTap working for the chrome - // process we shouldn't need to do this at all. - if (event.touches.Length() == 1) { - WidgetMouseEvent mouseEvent = aInput.ToWidgetMouseEvent(this); - if (mouseEvent.message != NS_EVENT_NULL) { - mouseEvent.mFlags.mNoCrossProcessBoundaryForwarding = (rv == nsEventStatus_eConsumeNoDefault); - DispatchEvent(&mouseEvent, rv); - } - } } From 4785d2a14a3bfc323b1726168b6c34f7c4d3eb93 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Sun, 1 Feb 2015 17:12:14 -0600 Subject: [PATCH 13/16] Bug 1107843. When computing the transform matrix for a preserve-3d child just include the final translation right away, instead of doing two translations that add and subtract to increase the accuracy. r=mattwoodrow --- layout/base/nsDisplayList.cpp | 8 +++++--- layout/reftests/bugs/reftest.list | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 3e66c97b5d5f..0e7a2006eb87 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -5207,11 +5207,13 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp aAppUnitsPerPixel, nullptr, aOutAncestor, !frame->IsTransformed()); - result.ChangeBasis(offsetBetweenOrigins); - result = result * parent; if (aOffsetByOrigin) { - result.Translate(roundedOrigin); + result.Translate(-aProperties.mToTransformOrigin); + result.TranslatePost(offsetBetweenOrigins); + } else { + result.ChangeBasis(offsetBetweenOrigins); } + result = result * parent; return result; } diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index f97d0dc78d1e..f477122ea9c1 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1848,7 +1848,7 @@ test-pref(dom.webcomponents.enabled,true) == 1066554-1.html 1066554-1-ref.html == 1069716-1.html 1069716-1-ref.html == 1078262-1.html about:blank test-pref(layout.testing.overlay-scrollbars.always-visible,false) == 1081072-1.html 1081072-1-ref.html -fuzzy-if(winWidget&&!layersGPUAccelerated,1,31) fuzzy-if(B2G,128,75) == 1081185-1.html 1081185-1-ref.html # fuzzy with event-regions, see bug 1107843 +fuzzy-if(B2G,128,75) == 1081185-1.html 1081185-1-ref.html # fuzzy with event-regions, see bug 1107843 == 1097437-1.html 1097437-1-ref.html == 1103258-1.html 1103258-1-ref.html # assertion crash test with layers culling test == 1105137-1.html 1105137-1-ref.html From 4cc44227f5f5370f250802546bccf2acdadbbb1c Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Sun, 1 Feb 2015 20:26:12 -0800 Subject: [PATCH 14/16] Bug 1120369 followup, touch CLOBBER to fix this CLOSED TREE --HG-- extra : rebase_source : 9c3cd7f1ba303bc733b0ab24fac7ab901e79ffc3 --- CLOBBER | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLOBBER b/CLOBBER index e0e95faab149..b9b501c611de 100644 --- a/CLOBBER +++ b/CLOBBER @@ -22,4 +22,4 @@ # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. -Bug 1109248 - This needed a CLOBBER on Windows and OSX. +Bug 1120369 - Needed a CLOBBER on at least Linux and OSX. From 9dd28021aa7b43c11777b5497fc2fa55e0a8adf1 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Fri, 30 Jan 2015 22:36:12 -0800 Subject: [PATCH 15/16] Bug 1120410 - Adjust fuzzy conditions for 413361-1.html to cover B2G and older-Android too CLOSED TREE --HG-- extra : rebase_source : c0e3057c686a86353e903782e1cbadab17957b61 --- layout/reftests/bugs/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index f477122ea9c1..3a5a8fdf9c3e 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -971,7 +971,7 @@ fails == 413027-3.html 413027-3-ref.html == 413286-5.html 413286-5-ref.html == 413286-6.html 413286-6-ref.html skip-if(cocoaWidget) == 413292-1.html 413292-1-ref.html # disabling due to failure loading on some mac tinderboxes. See bug 432954 -fuzzy-if(Android&&AndroidVersion>=15,11,15) == 413361-1.html 413361-1-ref.html +fuzzy-if(B2G||Android,11,15) == 413361-1.html 413361-1-ref.html # bug 1128229 == 413840-background-unchanged.html 413840-background-unchanged-ref.html == 413840-ltr-offsets.html 413840-ltr-offsets-ref.html == 413840-rtl-offsets.html 413840-rtl-offsets-ref.html From 67b6d770d025fdb9b87e88534f2cb8cf9629a89a Mon Sep 17 00:00:00 2001 From: Paolo Amadini Date: Sun, 1 Feb 2015 19:38:09 +0000 Subject: [PATCH 16/16] Bug 1124516 - Telemetry: Record the time in days each saved login was last used. r=MattN --- .../components/passwordmgr/nsLoginManager.js | 67 +++++-- .../passwordmgr/test/unit/test_telemetry.js | 183 ++++++++++++++++++ .../passwordmgr/test/unit/xpcshell.ini | 1 + toolkit/components/telemetry/Histograms.json | 9 +- 4 files changed, 242 insertions(+), 18 deletions(-) create mode 100644 toolkit/components/passwordmgr/test/unit/test_telemetry.js diff --git a/toolkit/components/passwordmgr/nsLoginManager.js b/toolkit/components/passwordmgr/nsLoginManager.js index 1044e4dd90a2..3b59e401398d 100644 --- a/toolkit/components/passwordmgr/nsLoginManager.js +++ b/toolkit/components/passwordmgr/nsLoginManager.js @@ -20,6 +20,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task", XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils", "resource://gre/modules/BrowserUtils.jsm"); +const MS_PER_DAY = 24 * 60 * 60 * 1000; + var debug = false; function log(...pieces) { function generateLogMessage(args) { @@ -201,34 +203,65 @@ LoginManager.prototype = { "passwordmgr-storage-replace-complete", null); }.bind(this)); } else if (topic == "gather-telemetry") { - this._pwmgr._gatherTelemetry(); + // When testing, the "data" parameter is a string containing the + // reference time in milliseconds for time-based statistics. + this._pwmgr._gatherTelemetry(data ? parseInt(data) + : new Date().getTime()); } else { log("Oops! Unexpected notification:", topic); } } }, - _gatherTelemetry : function() { - let numPasswordsBlocklist = Services.telemetry.getHistogramById("PWMGR_BLOCKLIST_NUM_SITES"); - numPasswordsBlocklist.clear(); - numPasswordsBlocklist.add(this.getAllDisabledHosts({}).length); + /** + * Collects statistics about the current logins and settings. The telemetry + * histograms used here are not accumulated, but are reset each time this + * function is called, since it can be called multiple times in a session. + * + * This function might also not be called at all in the current session. + * + * @param referenceTimeMs + * Current time used to calculate time-based statistics, expressed as + * the number of milliseconds since January 1, 1970, 00:00:00 UTC. + * This is set to a fake value during unit testing. + */ + _gatherTelemetry : function (referenceTimeMs) { + function clearAndGetHistogram(histogramId) { + let histogram = Services.telemetry.getHistogramById(histogramId); + histogram.clear(); + return histogram; + } - let numPasswordsHist = Services.telemetry.getHistogramById("PWMGR_NUM_SAVED_PASSWORDS"); - numPasswordsHist.clear(); - numPasswordsHist.add(this.countLogins("", "", "")); + clearAndGetHistogram("PWMGR_BLOCKLIST_NUM_SITES").add( + this.getAllDisabledHosts({}).length + ); + clearAndGetHistogram("PWMGR_NUM_SAVED_PASSWORDS").add( + this.countLogins("", "", "") + ); - let isPwdSavedEnabledHist = Services.telemetry.getHistogramById("PWMGR_SAVING_ENABLED"); - isPwdSavedEnabledHist.clear(); - isPwdSavedEnabledHist.add(this._remember); + // This is a boolean histogram, and not a flag, because we don't want to + // record any value if _gatherTelemetry is not called. + clearAndGetHistogram("PWMGR_SAVING_ENABLED").add(this._remember); // Don't try to get logins if MP is enabled, since we don't want to show a MP prompt. - if (this.isLoggedIn) { - let logins = this.getAllLogins({}); + if (!this.isLoggedIn) { + return; + } - let usernameHist = Services.telemetry.getHistogramById("PWMGR_USERNAME_PRESENT"); - usernameHist.clear(); - for (let login of logins) { - usernameHist.add(!!login.username); + let logins = this.getAllLogins({}); + + let usernamePresentHistogram = clearAndGetHistogram("PWMGR_USERNAME_PRESENT"); + let loginLastUsedDaysHistogram = clearAndGetHistogram("PWMGR_LOGIN_LAST_USED_DAYS"); + + for (let login of logins) { + usernamePresentHistogram.add(!!login.username); + + login.QueryInterface(Ci.nsILoginMetaInfo); + let timeLastUsedAgeMs = referenceTimeMs - login.timeLastUsed; + if (timeLastUsedAgeMs > 0) { + loginLastUsedDaysHistogram.add( + Math.floor(timeLastUsedAgeMs / MS_PER_DAY) + ); } } }, diff --git a/toolkit/components/passwordmgr/test/unit/test_telemetry.js b/toolkit/components/passwordmgr/test/unit/test_telemetry.js new file mode 100644 index 000000000000..8f427a88a363 --- /dev/null +++ b/toolkit/components/passwordmgr/test/unit/test_telemetry.js @@ -0,0 +1,183 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests the statistics and other counters reported through telemetry. + */ + +"use strict"; + +//////////////////////////////////////////////////////////////////////////////// +//// Globals + +const MS_PER_DAY = 24 * 60 * 60 * 1000; + +// To prevent intermittent failures when the test is executed at a time that is +// very close to a day boundary, we make it deterministic by using a static +// reference date for all the time-based statistics. +const gReferenceTimeMs = new Date("2000-01-01T00:00:00").getTime(); + +// Returns a milliseconds value to use with nsILoginMetaInfo properties, falling +// approximately in the middle of the specified number of days before the +// reference time, where zero days indicates a time within the past 24 hours. +let daysBeforeMs = days => gReferenceTimeMs - (days + 0.5) * MS_PER_DAY; + +/** + * Contains metadata that will be attached to test logins in order to verify + * that the statistics collection is working properly. Most properties of the + * logins are initialized to the default test values already. + * + * If you update this data or any of the telemetry histograms it checks, you'll + * probably need to update the expected statistics in the test below. + */ +const StatisticsTestData = [ + { + timeLastUsed: daysBeforeMs(0), + }, + { + timeLastUsed: daysBeforeMs(1), + }, + { + timeLastUsed: daysBeforeMs(7), + }, + { + username: "", + timeLastUsed: daysBeforeMs(7), + }, + { + username: "", + timeLastUsed: daysBeforeMs(30), + }, + { + username: "", + timeLastUsed: daysBeforeMs(31), + }, + { + timeLastUsed: daysBeforeMs(365), + }, + { + username: "", + timeLastUsed: daysBeforeMs(366), + }, + { + // If the login was saved in the future, it is ignored for statistiscs. + timeLastUsed: daysBeforeMs(-1), + }, + { + timeLastUsed: daysBeforeMs(1000), + }, +]; + +/** + * Triggers the collection of those statistics that are not accumulated each + * time an action is taken, but are a static snapshot of the current state. + */ +function triggerStatisticsCollection() { + Services.obs.notifyObservers(null, "gather-telemetry", "" + gReferenceTimeMs); +} + +/** + * Tests the telemetry histogram with the given ID contains only the specified + * non-zero ranges, expressed in the format { range1: value1, range2: value2 }. + */ +function testHistogram(histogramId, expectedNonZeroRanges) { + let snapshot = Services.telemetry.getHistogramById(histogramId).snapshot(); + + // Compute the actual ranges in the format { range1: value1, range2: value2 }. + let actualNonZeroRanges = {}; + for (let [index, range] of snapshot.ranges.entries()) { + let value = snapshot.counts[index]; + if (value > 0) { + actualNonZeroRanges[range] = value; + } + } + + // These are stringified to visualize the differences between the values. + do_print("Testing histogram: " + histogramId); + do_check_eq(JSON.stringify(actualNonZeroRanges), + JSON.stringify(expectedNonZeroRanges)); +} + +//////////////////////////////////////////////////////////////////////////////// +//// Tests + +/** + * Enable local telemetry recording for the duration of the tests, and prepare + * the test data that will be used by the following tests. + */ +add_task(function test_initialize() { + let oldCanRecord = Services.telemetry.canRecord; + Services.telemetry.canRecord = true; + do_register_cleanup(function () { + Services.telemetry.canRecord = oldCanRecord; + }); + + let uniqueNumber = 1; + for (let loginModifications of StatisticsTestData) { + loginModifications.hostname = `http://${uniqueNumber++}.example.com`; + Services.logins.addLogin(TestData.formLogin(loginModifications)); + } +}); + +/** + * Tests the collection of statistics related to login metadata. + */ +add_task(function test_logins_statistics() { + // Repeat the operation twice to test that histograms are not accumulated. + for (let repeating of [false, true]) { + triggerStatisticsCollection(); + + // Should record 1 in the bucket corresponding to the number of passwords. + testHistogram("PWMGR_NUM_SAVED_PASSWORDS", + { 10: 1 }); + + // For each saved login, should record 1 in the bucket corresponding to the + // age in days since the login was last used. + testHistogram("PWMGR_LOGIN_LAST_USED_DAYS", + { 0: 1, 1: 1, 7: 2, 29: 2, 356: 2, 750: 1 }); + + // Should record the number of logins without a username in bucket 0, and + // the number of logins with a username in bucket 1. + testHistogram("PWMGR_USERNAME_PRESENT", + { 0: 4, 1: 6 }); + } +}); + +/** + * Tests the collection of statistics related to hosts for which passowrd saving + * has been explicitly disabled. + */ +add_task(function test_disabledHosts_statistics() { + // Should record 1 in the bucket corresponding to the number of sites for + // which password saving is disabled. + Services.logins.setLoginSavingEnabled("http://www.example.com", false); + triggerStatisticsCollection(); + testHistogram("PWMGR_BLOCKLIST_NUM_SITES", { 1: 1 }); + + Services.logins.setLoginSavingEnabled("http://www.example.com", true); + triggerStatisticsCollection(); + testHistogram("PWMGR_BLOCKLIST_NUM_SITES", { 0: 1 }); +}); + +/** + * Tests the collection of statistics related to general settings. + */ +add_task(function test_settings_statistics() { + let oldRememberSignons = Services.prefs.getBoolPref("signon.rememberSignons"); + do_register_cleanup(function () { + Services.prefs.setBoolPref("signon.rememberSignons", oldRememberSignons); + }); + + // Repeat the operation twice per value to test that histograms are reset. + for (let remember of [false, true, false, true]) { + // This change should be observed immediately by the login service. + Services.prefs.setBoolPref("signon.rememberSignons", remember); + + triggerStatisticsCollection(); + + // Should record 1 in either bucket 0 or bucket 1 based on the preference. + testHistogram("PWMGR_SAVING_ENABLED", remember ? { 1: 1 } : { 0: 1 }); + } +}); diff --git a/toolkit/components/passwordmgr/test/unit/xpcshell.ini b/toolkit/components/passwordmgr/test/unit/xpcshell.ini index 4660e0790b6a..32826ce8290f 100644 --- a/toolkit/components/passwordmgr/test/unit/xpcshell.ini +++ b/toolkit/components/passwordmgr/test/unit/xpcshell.ini @@ -24,3 +24,4 @@ skip-if = os != "android" [test_logins_search.js] [test_notifications.js] [test_storage.js] +[test_telemetry.js] diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 4ebccbc4c85e..43ec2d3d3766 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -7268,7 +7268,14 @@ "high": 750, "n_buckets" : 50, "extended_statistics_ok": true, - "description": "The number of saved signons in storage" + "description": "Total number of saved logins, including those that cannot be decrypted" + }, + "PWMGR_LOGIN_LAST_USED_DAYS": { + "expires_in_version": "never", + "kind": "exponential", + "high": 750, + "n_buckets" : 40, + "description": "Time in days each saved login was last used" }, "PWMGR_SAVING_ENABLED": { "expires_in_version": "never",