diff --git a/accessible/src/base/nsAccessiblePivot.cpp b/accessible/src/base/nsAccessiblePivot.cpp index 8690a363e22..5a44ca43b8e 100644 --- a/accessible/src/base/nsAccessiblePivot.cpp +++ b/accessible/src/base/nsAccessiblePivot.cpp @@ -61,7 +61,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsAccessiblePivot) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPosition) uint32_t i, length = tmp->mObservers.Length(); for (i = 0; i < length; ++i) { - cb.NoteXPCOMChild(tmp->mObservers[i]); + cb.NoteXPCOMChild(tmp->mObservers.ElementAt(i)); } NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END diff --git a/content/media/DecoderTraits.cpp b/content/media/DecoderTraits.cpp index b3a10d395e0..64dfa7456b1 100644 --- a/content/media/DecoderTraits.cpp +++ b/content/media/DecoderTraits.cpp @@ -10,6 +10,9 @@ #ifdef MOZ_MEDIA_PLUGINS #include "MediaPluginHost.h" #endif +#ifdef MOZ_GSTREAMER +#include "mozilla/Preferences.h" +#endif namespace mozilla { diff --git a/dom/bluetooth/BluetoothHfpManager.cpp b/dom/bluetooth/BluetoothHfpManager.cpp index bffe034f9b0..7d749014cfe 100644 --- a/dom/bluetooth/BluetoothHfpManager.cpp +++ b/dom/bluetooth/BluetoothHfpManager.cpp @@ -823,6 +823,7 @@ BluetoothHfpManager::SetupCIND(int aCallIndex, int aCallState, bool aInitial) if (!aInitial) { switch (currentCallState) { case nsIRadioInterfaceLayer::CALL_STATE_INCOMING: + case nsIRadioInterfaceLayer::CALL_STATE_BUSY: // Incoming call, no break sStopSendingRingFlag = true; case nsIRadioInterfaceLayer::CALL_STATE_DIALING: @@ -979,6 +980,7 @@ BluetoothHfpManager::OnDisconnect() NotifySettings(); } + sStopSendingRingFlag = true; sCINDItems[CINDType::CALL].value = CallState::NO_CALL; sCINDItems[CINDType::CALLSETUP].value = CallSetupState::NO_CALLSETUP; sCINDItems[CINDType::CALLHELD].value = CallHeldState::NO_CALLHELD; diff --git a/dom/system/gonk/RILContentHelper.js b/dom/system/gonk/RILContentHelper.js index ba6c5449265..b00edfeccfb 100644 --- a/dom/system/gonk/RILContentHelper.js +++ b/dom/system/gonk/RILContentHelper.js @@ -60,7 +60,7 @@ const RIL_IPC_MSG_NAMES = [ "RIL:SelectNetworkAuto", "RIL:CallStateChanged", "RIL:VoicemailNotification", - "RIL:VoicemailNumberChanged", + "RIL:VoicemailInfoChanged", "RIL:CallError", "RIL:CardLockResult", "RIL:USSDReceived", @@ -123,7 +123,13 @@ MobileICCInfo.prototype = { mcc: 0, mnc: 0, spn: null, - msisdn: null, + msisdn: null +}; + +function MobileVoicemailInfo() {} +MobileVoicemailInfo.prototype = { + number: null, + displayName: null }; function MobileConnectionInfo() {} @@ -241,6 +247,7 @@ function RILContentHelper() { this.iccInfo = new MobileICCInfo(); this.voiceConnectionInfo = new MobileConnectionInfo(); this.dataConnectionInfo = new MobileConnectionInfo(); + this.voicemailInfo = new MobileVoicemailInfo(); this.initRequests(); this.initMessageListener(RIL_IPC_MSG_NAMES); @@ -257,6 +264,7 @@ function RILContentHelper() { this.updateICCInfo(rilContext.icc, this.iccInfo); this.updateConnectionInfo(rilContext.voice, this.voiceConnectionInfo); this.updateConnectionInfo(rilContext.data, this.dataConnectionInfo); + this.updateVoicemailInfo(rilContext.voicemail, this.voicemailInfo); } RILContentHelper.prototype = { @@ -271,6 +279,12 @@ RILContentHelper.prototype = { interfaces: [Ci.nsIMobileConnectionProvider, Ci.nsIRILContentHelper]}), + updateVoicemailInfo: function updateVoicemailInfo(srcInfo, destInfo) { + for (let key in srcInfo) { + destInfo[key] = srcInfo[key]; + } + }, + updateICCInfo: function updateICCInfo(srcInfo, destInfo) { for (let key in srcInfo) { destInfo[key] = srcInfo[key]; @@ -553,8 +567,12 @@ RILContentHelper.prototype = { _enumerateTelephonyCallbacks: null, voicemailStatus: null, - voicemailNumber: null, - voicemailDisplayName: null, + get voicemailNumber() { + return this.voicemailInfo.number; + }, + get voicemailDisplayName() { + return this.voicemailInfo.displayName; + }, registerCallback: function registerCallback(callbackType, callback) { let callbacks = this[callbackType]; @@ -797,9 +815,8 @@ RILContentHelper.prototype = { case "RIL:VoicemailNotification": this.handleVoicemailNotification(msg.json); break; - case "RIL:VoicemailNumberChanged": - this.voicemailNumber = msg.json.number; - this.voicemailDisplayName = msg.json.alphaId; + case "RIL:VoicemailInfoChanged": + this.updateVoicemailInfo(msg.json, this.voicemailInfo); break; case "RIL:CardLockResult": if (msg.json.success) { diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index 87c10f74452..2c103233635 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -194,6 +194,8 @@ function RadioInterfaceLayer() { radioState: RIL.GECKO_RADIOSTATE_UNAVAILABLE, cardState: RIL.GECKO_CARDSTATE_UNAVAILABLE, icc: null, + voicemail: {number: null, + displayName: null}, // These objects implement the nsIDOMMozMobileConnectionInfo interface, // although the actual implementation lives in the content process. So are @@ -568,7 +570,7 @@ RadioInterfaceLayer.prototype = { } break; case "iccmbdn": - this._sendTargetMessage("voicemail", "RIL:VoicemailNumberChanged", message); + this.handleICCMbdn(message); break; case "USSDReceived": debug("USSDReceived " + JSON.stringify(message)); @@ -1477,6 +1479,15 @@ RadioInterfaceLayer.prototype = { } }, + handleICCMbdn: function handleICCMbdn(message) { + let voicemail = this.rilContext.voicemail; + + voicemail.number = message.number; + voicemail.displayName = message.alphaId; + + this._sendTargetMessage("voicemail", "RIL:VoicemailInfoChanged", voicemail); + }, + handleICCInfoChange: function handleICCInfoChange(message) { let oldIcc = this.rilContext.icc; this.rilContext.icc = message; diff --git a/dom/system/unix/QTMLocationProvider.h b/dom/system/unix/QTMLocationProvider.h index b6ed7ad70a4..f61ba833ae9 100644 --- a/dom/system/unix/QTMLocationProvider.h +++ b/dom/system/unix/QTMLocationProvider.h @@ -24,7 +24,7 @@ public: public Q_SLOTS: // QGeoPositionInfoSource - void positionUpdated(const QGeoPositionInfo&); + void positionUpdated(const QtMobility::QGeoPositionInfo&); private: ~QTMLocationProvider(); diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index 9e1c7f973ca..c780cb1aa62 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -926,6 +926,7 @@ public: static uint64_t GetD2DVRAMUsageDrawTarget(); static uint64_t GetD2DVRAMUsageSourceSurface(); + static void D2DCleanup(); private: static ID3D10Device1 *mD3D10Device; diff --git a/gfx/2d/DrawTargetD2D.cpp b/gfx/2d/DrawTargetD2D.cpp index 2113435dfb0..d82a5c9a511 100644 --- a/gfx/2d/DrawTargetD2D.cpp +++ b/gfx/2d/DrawTargetD2D.cpp @@ -2686,6 +2686,15 @@ DrawTargetD2D::factory() return mFactory; } +void +DrawTargetD2D::CleanupD2D() +{ + if (mFactory) { + mFactory->Release(); + mFactory = nullptr; + } +} + IDWriteFactory* DrawTargetD2D::GetDWriteFactory() { diff --git a/gfx/2d/DrawTargetD2D.h b/gfx/2d/DrawTargetD2D.h index 4575214beb1..1e8ed6350d7 100644 --- a/gfx/2d/DrawTargetD2D.h +++ b/gfx/2d/DrawTargetD2D.h @@ -128,6 +128,7 @@ public: void PopCachedLayer(ID2D1RenderTarget *aRT); static ID2D1Factory *factory(); + static void CleanupD2D(); static TemporaryRef CreateStrokeStyleForOptions(const StrokeOptions &aStrokeOptions); static IDWriteFactory *GetDWriteFactory(); diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp index 8ebbf2527b3..f20ec2ffef5 100644 --- a/gfx/2d/Factory.cpp +++ b/gfx/2d/Factory.cpp @@ -441,6 +441,12 @@ Factory::GetD2DVRAMUsageSourceSurface() return DrawTargetD2D::mVRAMUsageSS; } +void +Factory::D2DCleanup() +{ + DrawTargetD2D::CleanupD2D(); +} + #endif // XP_WIN TemporaryRef diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index acc43393481..acb2479e935 100644 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -385,6 +385,8 @@ gfxWindowsPlatform::~gfxWindowsPlatform() } #endif + mozilla::gfx::Factory::D2DCleanup(); + /* * Uninitialize COM */ diff --git a/js/src/ion/CodeGenerator.cpp b/js/src/ion/CodeGenerator.cpp index aa72a885147..62071975c3e 100644 --- a/js/src/ion/CodeGenerator.cpp +++ b/js/src/ion/CodeGenerator.cpp @@ -4213,6 +4213,122 @@ CodeGenerator::visitInArray(LInArray *lir) return true; } +bool +CodeGenerator::visitInstanceOfTypedO(LInstanceOfTypedO *ins) +{ + return emitInstanceOfTyped(ins, ins->mir()->prototypeObject()); +} + +bool +CodeGenerator::visitInstanceOfTypedV(LInstanceOfTypedV *ins) +{ + return emitInstanceOfTyped(ins, ins->mir()->prototypeObject()); +} + +// Wrap IsDelegate, which takes a Value for the lhs of an instanceof. +static bool +IsDelegateObject(JSContext *cx, HandleObject protoObj, HandleObject obj, JSBool *res) +{ + bool nres; + if (!IsDelegate(cx, protoObj, ObjectValue(*obj), &nres)) + return false; + *res = nres; + return true; +} + +typedef bool (*IsDelegateObjectFn)(JSContext *, HandleObject, HandleObject, JSBool *); +static const VMFunction IsDelegateObjectInfo = FunctionInfo(IsDelegateObject); + +bool +CodeGenerator::emitInstanceOfTyped(LInstruction *ins, RawObject prototypeObject) +{ + // This path implements fun_hasInstance when the function's prototype is + // known to be prototypeObject. + + Label done; + Register output = ToRegister(ins->getDef(0)); + + // If the lhs is a primitive, the result is false. + Register objReg; + if (ins->isInstanceOfTypedV()) { + Label isObject; + ValueOperand lhsValue = ToValue(ins, LInstanceOfTypedV::LHS); + masm.branchTestObject(Assembler::Equal, lhsValue, &isObject); + masm.mov(Imm32(0), output); + masm.jump(&done); + masm.bind(&isObject); + objReg = masm.extractObject(lhsValue, output); + } else { + objReg = ToRegister(ins->toInstanceOfTypedO()->lhs()); + } + + // Crawl the lhs's prototype chain in a loop to search for prototypeObject. + // This follows the main loop of js::IsDelegate, though additionally breaks + // out of the loop on Proxy::LazyProto. + + // Load the lhs's prototype. + masm.loadPtr(Address(objReg, JSObject::offsetOfType()), output); + masm.loadPtr(Address(output, offsetof(types::TypeObject, proto)), output); + + Label testLazy; + { + Label loopPrototypeChain; + masm.bind(&loopPrototypeChain); + + // Test for the target prototype object. + Label notPrototypeObject; + masm.branchPtr(Assembler::NotEqual, output, ImmGCPtr(prototypeObject), ¬PrototypeObject); + masm.mov(Imm32(1), output); + masm.jump(&done); + masm.bind(¬PrototypeObject); + + JS_ASSERT(uintptr_t(Proxy::LazyProto) == 1); + + // Test for NULL or Proxy::LazyProto + masm.branchPtr(Assembler::BelowOrEqual, output, ImmWord(1), &testLazy); + + // Load the current object's prototype. + masm.loadPtr(Address(output, JSObject::offsetOfType()), output); + masm.loadPtr(Address(output, offsetof(types::TypeObject, proto)), output); + + masm.jump(&loopPrototypeChain); + } + + // Make a VM call if an object with a lazy proto was found on the prototype + // chain. This currently occurs only for cross compartment wrappers, which + // we do not expect to be compared with non-wrapper functions from this + // compartment. Otherwise, we stopped on a NULL prototype and the output + // register is already correct. + + OutOfLineCode *ool = oolCallVM(IsDelegateObjectInfo, ins, + (ArgList(), ImmGCPtr(prototypeObject), objReg), + StoreRegisterTo(output)); + + // Regenerate the original lhs object for the VM call. + Label regenerate, *lazyEntry; + if (objReg != output) { + lazyEntry = ool->entry(); + } else { + masm.bind(®enerate); + lazyEntry = ®enerate; + if (ins->isInstanceOfTypedV()) { + ValueOperand lhsValue = ToValue(ins, LInstanceOfTypedV::LHS); + objReg = masm.extractObject(lhsValue, output); + } else { + objReg = ToRegister(ins->toInstanceOfTypedO()->lhs()); + } + JS_ASSERT(objReg == output); + masm.jump(ool->entry()); + } + + masm.bind(&testLazy); + masm.branchPtr(Assembler::Equal, output, ImmWord(1), lazyEntry); + + masm.bind(&done); + masm.bind(ool->rejoin()); + return true; +} + bool CodeGenerator::visitInstanceOfO(LInstanceOfO *ins) { diff --git a/js/src/ion/CodeGenerator.h b/js/src/ion/CodeGenerator.h index a286c5512b4..5436bd61ceb 100644 --- a/js/src/ion/CodeGenerator.h +++ b/js/src/ion/CodeGenerator.h @@ -168,9 +168,12 @@ class CodeGenerator : public CodeGeneratorSpecific bool visitCallDeleteProperty(LCallDeleteProperty *lir); bool visitBitNotV(LBitNotV *lir); bool visitBitOpV(LBitOpV *lir); + bool emitInstanceOfTyped(LInstruction *ins, RawObject prototypeObject); bool emitInstanceOf(LInstruction *ins, Register rhs); bool visitIn(LIn *ins); bool visitInArray(LInArray *ins); + bool visitInstanceOfTypedO(LInstanceOfTypedO *ins); + bool visitInstanceOfTypedV(LInstanceOfTypedV *ins); bool visitInstanceOfO(LInstanceOfO *ins); bool visitInstanceOfV(LInstanceOfV *ins); bool visitFunctionBoundary(LFunctionBoundary *lir); diff --git a/js/src/ion/IonBuilder.cpp b/js/src/ion/IonBuilder.cpp index bba29b7adb1..2ea2d947219 100644 --- a/js/src/ion/IonBuilder.cpp +++ b/js/src/ion/IonBuilder.cpp @@ -6498,9 +6498,37 @@ IonBuilder::jsop_in_dense() bool IonBuilder::jsop_instanceof() { - MDefinition *proto = current->pop(); + MDefinition *rhs = current->pop(); MDefinition *obj = current->pop(); - MInstanceOf *ins = new MInstanceOf(obj, proto); + + TypeOracle::BinaryTypes types = oracle->binaryTypes(script_, pc); + + // If this is an 'x instanceof function' operation and we can determine the + // exact function and prototype object being tested for, use a typed path. + do { + RawObject rhsObject = types.rhsTypes ? types.rhsTypes->getSingleton() : NULL; + if (!rhsObject || !rhsObject->isFunction() || rhsObject->isBoundFunction()) + break; + + types::TypeObject *rhsType = rhsObject->getType(cx); + if (!rhsType || rhsType->unknownProperties()) + break; + + types::HeapTypeSet *protoTypes = + rhsType->getProperty(cx, NameToId(cx->names().classPrototype), false); + RawObject protoObject = protoTypes ? protoTypes->getSingleton(cx) : NULL; + if (!protoObject) + break; + + MInstanceOfTyped *ins = new MInstanceOfTyped(obj, protoObject); + + current->add(ins); + current->push(ins); + + return resumeAfter(ins); + } while (false); + + MInstanceOf *ins = new MInstanceOf(obj, rhs); current->add(ins); current->push(ins); diff --git a/js/src/ion/LIR-Common.h b/js/src/ion/LIR-Common.h index c240d7e40dc..00b91ddc2b2 100644 --- a/js/src/ion/LIR-Common.h +++ b/js/src/ion/LIR-Common.h @@ -3143,6 +3143,41 @@ class LIn : public LCallInstructionHelper<1, BOX_PIECES+1, 0> static const size_t RHS = BOX_PIECES; }; +class LInstanceOfTypedO : public LInstructionHelper<1, 1, 0> +{ + public: + LIR_HEADER(InstanceOfTypedO); + LInstanceOfTypedO(const LAllocation &lhs) { + setOperand(0, lhs); + } + + MInstanceOfTyped *mir() const { + return mir_->toInstanceOfTyped(); + } + + const LAllocation *lhs() { + return getOperand(0); + } +}; + +class LInstanceOfTypedV : public LInstructionHelper<1, BOX_PIECES, 0> +{ + public: + LIR_HEADER(InstanceOfTypedV); + LInstanceOfTypedV() { + } + + MInstanceOfTyped *mir() const { + return mir_->toInstanceOfTyped(); + } + + const LAllocation *lhs() { + return getOperand(LHS); + } + + static const size_t LHS = 0; +}; + class LInstanceOfO : public LInstructionHelper<1, 2, 2> { public: diff --git a/js/src/ion/LOpcodes.h b/js/src/ion/LOpcodes.h index d78634a2d3b..be0918ca31c 100644 --- a/js/src/ion/LOpcodes.h +++ b/js/src/ion/LOpcodes.h @@ -169,6 +169,8 @@ _(Round) \ _(In) \ _(InArray) \ + _(InstanceOfTypedO) \ + _(InstanceOfTypedV) \ _(InstanceOfO) \ _(InstanceOfV) \ _(InterruptCheck) \ diff --git a/js/src/ion/Lowering.cpp b/js/src/ion/Lowering.cpp index 0b1779eac96..a8a8e6ab458 100644 --- a/js/src/ion/Lowering.cpp +++ b/js/src/ion/Lowering.cpp @@ -1924,6 +1924,22 @@ LIRGenerator::visitIn(MIn *ins) return defineVMReturn(lir, ins) && assignSafepoint(lir, ins); } +bool +LIRGenerator::visitInstanceOfTyped(MInstanceOfTyped *ins) +{ + MDefinition *lhs = ins->getOperand(0); + + JS_ASSERT(lhs->type() == MIRType_Value || lhs->type() == MIRType_Object); + + if (lhs->type() == MIRType_Object) { + LInstanceOfTypedO *lir = new LInstanceOfTypedO(useRegister(lhs)); + return define(lir, ins) && assignSafepoint(lir, ins); + } + + LInstanceOfTypedV *lir = new LInstanceOfTypedV(); + return useBox(lir, LInstanceOfTypedV::LHS, lhs) && define(lir, ins) && assignSafepoint(lir, ins); +} + bool LIRGenerator::visitInstanceOf(MInstanceOf *ins) { @@ -1933,7 +1949,6 @@ LIRGenerator::visitInstanceOf(MInstanceOf *ins) JS_ASSERT(lhs->type() == MIRType_Value || lhs->type() == MIRType_Object); JS_ASSERT(rhs->type() == MIRType_Object); - // InstanceOf with non-object will always return false if (lhs->type() == MIRType_Object) { LInstanceOfO *lir = new LInstanceOfO(useRegister(lhs), useRegister(rhs), temp(), temp()); return define(lir, ins) && assignSafepoint(lir, ins); diff --git a/js/src/ion/Lowering.h b/js/src/ion/Lowering.h index cfe005924f4..de9b93d1bf3 100644 --- a/js/src/ion/Lowering.h +++ b/js/src/ion/Lowering.h @@ -184,6 +184,7 @@ class LIRGenerator : public LIRGeneratorSpecific bool visitThrow(MThrow *ins); bool visitIn(MIn *ins); bool visitInArray(MInArray *ins); + bool visitInstanceOfTyped(MInstanceOfTyped *ins); bool visitInstanceOf(MInstanceOf *ins); bool visitFunctionBoundary(MFunctionBoundary *ins); bool visitSetDOMProperty(MSetDOMProperty *ins); diff --git a/js/src/ion/MIR.h b/js/src/ion/MIR.h index 372f0903e19..2a0081af31d 100644 --- a/js/src/ion/MIR.h +++ b/js/src/ion/MIR.h @@ -5245,7 +5245,33 @@ class MInArray } }; -// Implementation for instanceof operator. +// Implementation for instanceof operator with specific rhs. +class MInstanceOfTyped + : public MUnaryInstruction, + public InstanceOfPolicy +{ + CompilerRootObject protoObj_; + + public: + MInstanceOfTyped(MDefinition *obj, RawObject proto) + : MUnaryInstruction(obj) + { + protoObj_ = proto; + setResultType(MIRType_Boolean); + } + + INSTRUCTION_HEADER(InstanceOfTyped); + + TypePolicy *typePolicy() { + return this; + } + + RawObject prototypeObject() { + return protoObj_; + } +}; + +// Implementation for instanceof operator with unknown rhs. class MInstanceOf : public MBinaryInstruction, public InstanceOfPolicy diff --git a/js/src/ion/MOpcodes.h b/js/src/ion/MOpcodes.h index b1e636011b1..69e266af26f 100644 --- a/js/src/ion/MOpcodes.h +++ b/js/src/ion/MOpcodes.h @@ -133,6 +133,7 @@ namespace ion { _(Floor) \ _(Round) \ _(In) \ + _(InstanceOfTyped) \ _(InstanceOf) \ _(InterruptCheck) \ _(FunctionBoundary) \ diff --git a/js/src/ion/TypePolicy.cpp b/js/src/ion/TypePolicy.cpp index 9da2a4db01c..13fb0bd2d24 100644 --- a/js/src/ion/TypePolicy.cpp +++ b/js/src/ion/TypePolicy.cpp @@ -386,9 +386,12 @@ InstanceOfPolicy::adjustInputs(MInstruction *def) BoxPolicy<0>::staticAdjustInputs(def); } - // Unbox second operand forcefully to an object, - // so it bailouts with other types - ObjectPolicy<1>::staticAdjustInputs(def); + if (def->numOperands() == 2) { + // Unbox second operand forcefully to an object, + // so it bailouts with other types + ObjectPolicy<1>::staticAdjustInputs(def); + } + return true; } diff --git a/js/src/ion/TypePolicy.h b/js/src/ion/TypePolicy.h index 52e66b00947..77d7eda0d41 100644 --- a/js/src/ion/TypePolicy.h +++ b/js/src/ion/TypePolicy.h @@ -190,8 +190,8 @@ class CallSetElementPolicy : public SingleObjectPolicy bool adjustInputs(MInstruction *def); }; -// First operand will be boxed to an Value (except for an object) -// Second operand will forcefully be unboxed to an object +// First operand will be boxed to a Value (except for an object) +// Second operand (if specified) will forcefully be unboxed to an object class InstanceOfPolicy : public TypePolicy { public: diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 7d3e3eb59d3..ad4a6e29ade 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -444,8 +444,7 @@ JSRuntime::cloneSelfHostedFunctionScript(JSContext *cx, Handle na } bool -JSRuntime::cloneSelfHostedValue(JSContext *cx, Handle name, HandleObject holder, - MutableHandleValue vp) +JSRuntime::cloneSelfHostedValue(JSContext *cx, Handle name, MutableHandleValue vp) { RootedValue funVal(cx); if (!getUnclonedSelfHostedValue(cx, name, &funVal)) @@ -458,15 +457,15 @@ JSRuntime::cloneSelfHostedValue(JSContext *cx, Handle name, Handl */ if (cx->global() == selfHostedGlobal_) { vp.set(funVal); - } else if (funVal.toObject().isFunction()){ + } else if (funVal.isObject() && funVal.toObject().isFunction()) { RootedFunction fun(cx, funVal.toObject().toFunction()); RootedObject clone(cx, CloneFunctionObject(cx, fun, cx->global(), fun->getAllocKind())); if (!clone) return false; vp.set(ObjectValue(*clone)); + } else { + vp.set(UndefinedValue()); } - DebugOnly ok = JS_DefinePropertyById(cx, holder, NameToId(name), vp, NULL, NULL, 0); - JS_ASSERT(ok); return true; } diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 3b4ad085cca..603b9d3b7bf 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -560,7 +560,7 @@ struct JSRuntime : js::RuntimeFriendFields bool cloneSelfHostedFunctionScript(JSContext *cx, js::Handle name, js::Handle targetFun); bool cloneSelfHostedValue(JSContext *cx, js::Handle name, - js::HandleObject holder, js::MutableHandleValue vp); + js::MutableHandleValue vp); /* Base address of the native stack for the current thread. */ uintptr_t nativeStackBase; diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 8d0648a63e9..e3adcbf1f29 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -3582,6 +3582,23 @@ GetMaxArgs(JSContext *cx, unsigned arg, jsval *vp) return true; } +static JSBool +GetSelfHostedValue(JSContext *cx, unsigned argc, jsval *vp) +{ + CallArgs args = CallArgsFromVp(argc, vp); + + if (argc != 1 || !args[0].isString()) { + JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_INVALID_ARGS, + "getSelfHostedValue"); + return false; + } + RootedAtom srcAtom(cx, ToAtom(cx, args[0])); + if (!srcAtom) + return false; + RootedPropertyName srcName(cx, srcAtom->asPropertyName()); + return cx->runtime->cloneSelfHostedValue(cx, srcName, args.rval()); +} + static JSFunctionSpecWithHelp shell_functions[] = { JS_FN_HELP("version", Version, 0, 0, "version([number])", @@ -3894,6 +3911,11 @@ static JSFunctionSpecWithHelp shell_functions[] = { " rooting hazards. This is helpful to reduce the time taken when interpreting\n" " heavily numeric code."), + JS_FN_HELP("getSelfHostedValue", GetSelfHostedValue, 1, 0, +"getSelfHostedValue()", +" Get a self-hosted value by its name. Note that these values don't get \n" +" cached, so repeatedly getting the same value creates multiple distinct clones."), + JS_FS_HELP_END }; #ifdef MOZ_PROFILING diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h index 344d10dde19..379a171121f 100644 --- a/js/src/vm/GlobalObject.h +++ b/js/src/vm/GlobalObject.h @@ -393,7 +393,11 @@ class GlobalObject : public JSObject if (HasDataProperty(cx, holder, id, value.address())) return true; Rooted rootedName(cx, name); - return cx->runtime->cloneSelfHostedValue(cx, rootedName, holder, value); + if (!cx->runtime->cloneSelfHostedValue(cx, rootedName, value)) + return false; + mozilla::DebugOnly ok = JS_DefinePropertyById(cx, holder, id, value, NULL, NULL, 0); + JS_ASSERT(ok); + return true; } inline RegExpStatics *getRegExpStatics() const; diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index ee7d328ed11..c3344fce340 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -666,7 +666,6 @@ nsDisplayListBuilder::~nsDisplayListBuilder() { nsCSSRendering::EndFrameTreesLocked(); - PL_FreeArenaPool(&mPool); PL_FinishArenaPool(&mPool); MOZ_COUNT_DTOR(nsDisplayListBuilder); } diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 9b10f1c03a8..0c7f6241d21 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -117,16 +117,6 @@ nsLineLayout::~nsLineLayout() NS_ASSERTION(nullptr == mRootSpan, "bad line-layout user"); - // PL_FreeArenaPool takes our memory and puts in on a global free list so - // that the next time an arena makes an allocation it will not have to go - // all the way down to malloc. This is desirable as this class is created - // and destroyed in a tight loop. - // - // I looked at the code. It is not technically necessary to call - // PL_FinishArenaPool() after PL_FreeArenaPool(), but from an API - // standpoint, I think we are susposed to. It will be very fast anyway, - // since PL_FreeArenaPool() has done all the work. - PL_FreeArenaPool(&mArena); PL_FinishArenaPool(&mArena); } diff --git a/widget/qt/mozqorientationsensorfilter.cpp b/widget/qt/mozqorientationsensorfilter.cpp index aeba6607aa6..db97fff1b43 100644 --- a/widget/qt/mozqorientationsensorfilter.cpp +++ b/widget/qt/mozqorientationsensorfilter.cpp @@ -12,6 +12,8 @@ #endif #include "nsXULAppAPI.h" +using namespace QtMobility; + int MozQOrientationSensorFilter::mWindowRotationAngle = 0; QTransform MozQOrientationSensorFilter::mWindowRotationTransform; diff --git a/widget/qt/mozqorientationsensorfilter.h b/widget/qt/mozqorientationsensorfilter.h index 856e9aee90a..d5f34dcf781 100644 --- a/widget/qt/mozqorientationsensorfilter.h +++ b/widget/qt/mozqorientationsensorfilter.h @@ -13,7 +13,8 @@ #include -class MozQOrientationSensorFilter : public QObject, public QOrientationFilter +class MozQOrientationSensorFilter : public QObject + , public QtMobility::QOrientationFilter { Q_OBJECT @@ -25,7 +26,7 @@ public: virtual ~MozQOrientationSensorFilter(){} - virtual bool filter(QOrientationReading* reading); + virtual bool filter(QtMobility::QOrientationReading* reading); static int GetWindowRotationAngle(); static QTransform& GetRotationTransform(); @@ -34,7 +35,10 @@ signals: void orientationChanged(); private: - bool filter(QSensorReading *reading) { return filter(static_cast(reading)); } + bool filter(QtMobility::QSensorReading *reading) + { + return filter(static_cast(reading)); + } static int mWindowRotationAngle; static QTransform mWindowRotationTransform; diff --git a/xpcom/glue/nsTObserverArray.h b/xpcom/glue/nsTObserverArray.h index 3f254d9e8f1..67c50e201c0 100644 --- a/xpcom/glue/nsTObserverArray.h +++ b/xpcom/glue/nsTObserverArray.h @@ -92,7 +92,8 @@ class nsAutoTObserverArray : protected nsTObserverArray_base { } // This method provides direct access to the i'th element of the array. - // The given index must be within the array bounds. + // The given index must be within the array bounds. If the underlying array + // may change during iteration, use an iterator instead of this function. // @param i The index of an element in the array. // @return A reference to the i'th element of the array. elem_type& ElementAt(index_type i) { @@ -118,15 +119,9 @@ class nsAutoTObserverArray : protected nsTObserverArray_base { return mArray.SafeElementAt(i, def); } - // Shorthand for ElementAt(i) - elem_type& operator[](index_type i) { - return ElementAt(i); - } - - // Shorthand for ElementAt(i) - const elem_type& operator[](index_type i) const { - return ElementAt(i); - } + // No operator[] is provided because the point of this class is to support + // allow modifying the array during iteration, and ElementAt() is not safe + // in those conditions. // // Search methods @@ -392,7 +387,7 @@ ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, aFlags |= CycleCollectionEdgeNameArrayFlag; size_t length = aField.Length(); for (size_t i = 0; i < length; ++i) { - ImplCycleCollectionTraverse(aCallback, aField[i], aName, aFlags); + ImplCycleCollectionTraverse(aCallback, aField.ElementAt(i), aName, aFlags); } }