author | Terrence Cole <terrence@mozilla.com> |
Wed, 15 Oct 2014 14:26:52 -0700 | |
changeset 211745 | 5df7f0bf77fc0cd57c74d8830f461599ca60d280 |
parent 211744 | 157b1f4e4ed268b329bf3a802816f0d92ad34987 |
child 211746 | e2b5adc8894d34f1131cef3f0184122c7f3d5bac |
push id | 27686 |
push user | ryanvm@gmail.com |
push date | Wed, 22 Oct 2014 20:01:01 +0000 |
treeherder | mozilla-central@6066a2a0766f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jandem |
bugs | 1013001 |
milestone | 36.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -474,29 +474,29 @@ GeneratePrototypeGuards(JSContext *cx, I */ MOZ_ASSERT(obj != holder); if (obj->hasUncacheableProto()) { // Note: objectReg and scratchReg may be the same register, so we cannot // use objectReg in the rest of this function. masm.loadPtr(Address(objectReg, JSObject::offsetOfType()), scratchReg); Address proto(scratchReg, types::TypeObject::offsetOfProto()); - masm.branchNurseryPtr(Assembler::NotEqual, proto, - ImmMaybeNurseryPtr(obj->getProto()), failures); + masm.branchPtr(Assembler::NotEqual, proto, + ImmMaybeNurseryPtr(obj->getProto()), failures); } JSObject *pobj = IsCacheableDOMProxy(obj) ? obj->getTaggedProto().toObjectOrNull() : obj->getProto(); if (!pobj) return; while (pobj != holder) { if (pobj->hasUncacheableProto()) { MOZ_ASSERT(!pobj->hasSingletonType()); - masm.moveNurseryPtr(ImmMaybeNurseryPtr(pobj), scratchReg); + masm.movePtr(ImmMaybeNurseryPtr(pobj), scratchReg); Address objType(scratchReg, JSObject::offsetOfType()); masm.branchPtr(Assembler::NotEqual, objType, ImmGCPtr(pobj->type()), failures); } pobj = pobj->getProto(); } } // Note: This differs from IsCacheableProtoChain in BaselineIC.cpp in that @@ -809,17 +809,17 @@ GenerateReadSlot(JSContext *cx, IonScrip if (obj != holder) { // Note: this may clobber the object register if it's used as scratch. GeneratePrototypeGuards(cx, ion, masm, obj, holder, object, scratchReg, &prototypeFailures); if (holder) { // Guard on the holder's shape. holderReg = scratchReg; - masm.moveNurseryPtr(ImmMaybeNurseryPtr(holder), holderReg); + masm.movePtr(ImmMaybeNurseryPtr(holder), holderReg); masm.branchPtr(Assembler::NotEqual, Address(holderReg, JSObject::offsetOfShape()), ImmGCPtr(holder->lastProperty()), &prototypeFailures); } else { // The property does not exist. Guard on everything in the // prototype chain. JSObject *proto = obj->getTaggedProto().toObjectOrNull(); @@ -1023,17 +1023,17 @@ GenerateCallGetter(JSContext *cx, IonScr } // Note: this may clobber the object register if it's used as scratch. if (obj != holder) GeneratePrototypeGuards(cx, ion, masm, obj, holder, object, scratchReg, failures); // Guard on the holder's shape. Register holderReg = scratchReg; - masm.moveNurseryPtr(ImmMaybeNurseryPtr(holder), holderReg); + masm.movePtr(ImmMaybeNurseryPtr(holder), holderReg); masm.branchPtr(Assembler::NotEqual, Address(holderReg, JSObject::offsetOfShape()), ImmGCPtr(holder->lastProperty()), maybePopAndFail); if (spillObjReg) masm.pop(object); @@ -1497,17 +1497,17 @@ GetPropertyIC::tryAttachDOMProxyUnshadow // getprop. Register scratchReg = output().valueReg().scratchReg(); GeneratePrototypeGuards(cx, ion, masm, obj, holder, object(), scratchReg, &failures); // Rename scratch for clarity. Register holderReg = scratchReg; // Guard on the holder of the property - masm.moveNurseryPtr(ImmMaybeNurseryPtr(holder), holderReg); + masm.movePtr(ImmMaybeNurseryPtr(holder), holderReg); masm.branchPtr(Assembler::NotEqual, Address(holderReg, JSObject::offsetOfShape()), ImmGCPtr(holder->lastProperty()), &failures); if (canCache == CanAttachReadSlot) { EmitLoadSlot(masm, holder, shape, holderReg, output(), scratchReg); } else { @@ -2266,17 +2266,17 @@ GenerateCallSetter(JSContext *cx, IonScr Label protoFailure; Label protoSuccess; // Generate prototype/shape guards. if (obj != holder) GeneratePrototypeGuards(cx, ion, masm, obj, holder, object, scratchReg, &protoFailure); - masm.moveNurseryPtr(ImmMaybeNurseryPtr(holder), scratchReg); + masm.movePtr(ImmMaybeNurseryPtr(holder), scratchReg); masm.branchPtr(Assembler::NotEqual, Address(scratchReg, JSObject::offsetOfShape()), ImmGCPtr(holder->lastProperty()), &protoFailure); masm.jump(&protoSuccess); masm.bind(&protoFailure);
--- a/js/src/jit/IonMacroAssembler.cpp +++ b/js/src/jit/IonMacroAssembler.cpp @@ -246,37 +246,16 @@ template void MacroAssembler::guardObjec template void MacroAssembler::guardObjectType(Register obj, const TypeWrapper *types, Register scratch, Label *miss); template void MacroAssembler::guardType(const Address &address, types::Type type, Register scratch, Label *miss); template void MacroAssembler::guardType(const ValueOperand &value, types::Type type, Register scratch, Label *miss); -void -MacroAssembler::branchNurseryPtr(Condition cond, const Address &ptr1, ImmMaybeNurseryPtr ptr2, - Label *label) -{ -#ifdef JSGC_GENERATIONAL - if (ptr2.value && gc::IsInsideNursery(ptr2.value)) - embedsNurseryPointers_ = true; -#endif - branchPtr(cond, ptr1, ptr2, label); -} - -void -MacroAssembler::moveNurseryPtr(ImmMaybeNurseryPtr ptr, Register reg) -{ -#ifdef JSGC_GENERATIONAL - if (ptr.value && gc::IsInsideNursery(ptr.value)) - embedsNurseryPointers_ = true; -#endif - movePtr(ptr, reg); -} - template<typename S, typename T> static void StoreToTypedFloatArray(MacroAssembler &masm, int arrayType, const S &value, const T &dest) { switch (arrayType) { case Scalar::Float32: masm.storeFloat32(value, dest); break;
--- a/js/src/jit/IonMacroAssembler.h +++ b/js/src/jit/IonMacroAssembler.h @@ -178,17 +178,16 @@ class MacroAssembler : public MacroAssem MOZ_ASSERT(isInitialized()); masm.branchPtr(cond(), reg(), ptr_, jump()); } }; mozilla::Maybe<AutoRooter> autoRooter_; mozilla::Maybe<IonContext> ionContext_; mozilla::Maybe<AutoIonContextAlloc> alloc_; - bool embedsNurseryPointers_; // SPS instrumentation, only used for Ion caches. mozilla::Maybe<IonInstrumentation> spsInstrumentation_; jsbytecode *spsPc_; private: // This field is used to manage profiling instrumentation output. If // provided and enabled, then instrumentation will be emitted around call @@ -201,18 +200,17 @@ class MacroAssembler : public MacroAssem NonAssertingLabel sequentialFailureLabel_; NonAssertingLabel parallelFailureLabel_; public: // If instrumentation should be emitted, then the sps parameter should be // provided, but otherwise it can be safely omitted to prevent all // instrumentation from being emitted. MacroAssembler() - : embedsNurseryPointers_(false), - sps_(nullptr) + : sps_(nullptr) { IonContext *icx = GetIonContext(); JSContext *cx = icx->cx; if (cx) constructRoot(cx); if (!icx->temp) { MOZ_ASSERT(cx); @@ -225,18 +223,17 @@ class MacroAssembler : public MacroAssem m_buffer.id = icx->getNextAssemblerId(); #endif } // This constructor should only be used when there is no IonContext active // (for example, Trampoline-$(ARCH).cpp and IonCaches.cpp). explicit MacroAssembler(JSContext *cx, IonScript *ion = nullptr, JSScript *script = nullptr, jsbytecode *pc = nullptr) - : embedsNurseryPointers_(false), - sps_(nullptr) + : sps_(nullptr) { constructRoot(cx); ionContext_.emplace(cx, (js::jit::TempAllocator *)nullptr); alloc_.emplace(cx); moveResolver_.setAllocator(*ionContext_->temp); #ifdef JS_CODEGEN_ARM initWithAllocator(); m_buffer.id = GetIonContext()->getNextAssemblerId(); @@ -252,18 +249,17 @@ class MacroAssembler : public MacroAssem sps_->setPushed(script); } } } // asm.js compilation handles its own IonContext-pushing struct AsmJSToken {}; explicit MacroAssembler(AsmJSToken) - : embedsNurseryPointers_(false), - sps_(nullptr) + : sps_(nullptr) { #ifdef JS_CODEGEN_ARM initWithAllocator(); m_buffer.id = 0; #endif } void setInstrumentation(IonInstrumentation *sps) { @@ -283,20 +279,16 @@ class MacroAssembler : public MacroAssem MoveResolver &moveResolver() { return moveResolver_; } size_t instructionsSize() const { return size(); } - bool embedsNurseryPointers() const { - return embedsNurseryPointers_; - } - // Emits a test of a value against all types in a TypeSet. A scratch // register is required. template <typename Source, typename TypeSet> void guardTypeSet(const Source &address, const TypeSet *types, BarrierKind kind, Register scratch, Label *miss); template <typename TypeSet> void guardObjectType(Register obj, const TypeSet *types, Register scratch, Label *miss); template <typename Source> void guardType(const Source &address, types::Type type, Register scratch, Label *miss); @@ -699,20 +691,16 @@ class MacroAssembler : public MacroAssem callPreBarrier(address, type); jump(&done); align(8); bind(&done); } - void branchNurseryPtr(Condition cond, const Address &ptr1, ImmMaybeNurseryPtr ptr2, - Label *label); - void moveNurseryPtr(ImmMaybeNurseryPtr ptr, Register reg); - void canonicalizeDouble(FloatRegister reg) { Label notNaN; branchDouble(DoubleOrdered, reg, reg, ¬NaN); loadConstantDouble(JS::GenericNaN(), reg); bind(¬NaN); } void canonicalizeFloat(FloatRegister reg) {
--- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -2125,16 +2125,21 @@ MacroAssemblerARMCompat::movePtr(ImmWord ma_mov(Imm32(imm.value), dest); } void MacroAssemblerARMCompat::movePtr(ImmGCPtr imm, Register dest) { ma_mov(imm, dest); } void +MacroAssemblerARMCompat::movePtr(ImmMaybeNurseryPtr imm, Register dest) +{ + movePtr(noteMaybeNurseryPtr(imm), dest); +} +void MacroAssemblerARMCompat::movePtr(ImmPtr imm, Register dest) { movePtr(ImmWord(uintptr_t(imm.value)), dest); } void MacroAssemblerARMCompat::movePtr(AsmJSImmPtr imm, Register dest) { RelocStyle rs;
--- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -620,16 +620,19 @@ class MacroAssemblerARMCompat : public M } void push(ImmWord imm) { push(Imm32(imm.value)); } void push(ImmGCPtr imm) { ma_mov(imm, ScratchRegister); ma_push(ScratchRegister); } + void push(ImmMaybeNurseryPtr imm) { + push(noteMaybeNurseryPtr(imm)); + } void push(const Address &address) { ma_ldr(Operand(address.base, address.offset), ScratchRegister); ma_push(ScratchRegister); } void push(Register reg) { ma_push(reg); } void push(FloatRegister reg) { @@ -1043,16 +1046,19 @@ class MacroAssemblerARMCompat : public M ma_cmp(secondScratchReg_, ptr); return jumpWithPatch(label, cond); } void branchPtr(Condition cond, Address addr, ImmGCPtr ptr, Label *label) { ma_ldr(addr, secondScratchReg_); ma_cmp(secondScratchReg_, ptr); ma_b(label, cond); } + void branchPtr(Condition cond, Address addr, ImmMaybeNurseryPtr ptr, Label *label) { + branchPtr(cond, addr, noteMaybeNurseryPtr(ptr), label); + } void branchPtr(Condition cond, Address addr, ImmWord ptr, Label *label) { ma_ldr(addr, secondScratchReg_); ma_cmp(secondScratchReg_, ptr); ma_b(label, cond); } void branchPtr(Condition cond, Address addr, ImmPtr ptr, Label *label) { branchPtr(cond, addr, ImmWord(uintptr_t(ptr.value)), label); } @@ -1166,17 +1172,17 @@ class MacroAssemblerARMCompat : public M void tagValue(JSValueType type, Register payload, ValueOperand dest); void pushValue(ValueOperand val); void popValue(ValueOperand val); void pushValue(const Value &val) { jsval_layout jv = JSVAL_TO_IMPL(val); push(Imm32(jv.s.tag)); if (val.isMarkable()) - push(ImmGCPtr(reinterpret_cast<gc::Cell *>(val.toGCThing()))); + push(ImmMaybeNurseryPtr(reinterpret_cast<gc::Cell *>(val.toGCThing()))); else push(Imm32(jv.s.payload.i32)); } void pushValue(JSValueType type, Register reg) { push(ImmTag(JSVAL_TYPE_TO_TAG(type))); ma_push(reg); } void pushValue(const Address &addr); @@ -1317,16 +1323,17 @@ class MacroAssemblerARMCompat : public M void move32(Imm32 imm, Register dest); void move32(Register src, Register dest); void movePtr(Register src, Register dest); void movePtr(ImmWord imm, Register dest); void movePtr(ImmPtr imm, Register dest); void movePtr(AsmJSImmPtr imm, Register dest); void movePtr(ImmGCPtr imm, Register dest); + void movePtr(ImmMaybeNurseryPtr imm, Register dest); void load8SignExtend(const Address &address, Register dest); void load8SignExtend(const BaseIndex &src, Register dest); void load8ZeroExtend(const Address &address, Register dest); void load8ZeroExtend(const BaseIndex &src, Register dest); void load16SignExtend(const Address &address, Register dest);
--- a/js/src/jit/shared/Assembler-shared.h +++ b/js/src/jit/shared/Assembler-shared.h @@ -193,41 +193,60 @@ struct PatchedImmPtr { explicit PatchedImmPtr() : value(nullptr) { } explicit PatchedImmPtr(const void *value) : value(const_cast<void*>(value)) { } }; +class AssemblerShared; +class ImmGCPtr; + +// Used for immediates which require relocation and may be traced during minor GC. +class ImmMaybeNurseryPtr +{ + friend class AssemblerShared; + friend class ImmGCPtr; + const gc::Cell *value; + + ImmMaybeNurseryPtr() : value(0) {} + + public: + explicit ImmMaybeNurseryPtr(const gc::Cell *ptr) : value(ptr) + { + MOZ_ASSERT(!IsPoisonedPtr(ptr)); + + // asm.js shouldn't be creating GC things + MOZ_ASSERT(!IsCompilingAsmJS()); + } +}; + // Used for immediates which require relocation. -struct ImmGCPtr +class ImmGCPtr { + public: const gc::Cell *value; explicit ImmGCPtr(const gc::Cell *ptr) : value(ptr) { MOZ_ASSERT(!IsPoisonedPtr(ptr)); MOZ_ASSERT_IF(ptr, ptr->isTenured()); // asm.js shouldn't be creating GC things MOZ_ASSERT(!IsCompilingAsmJS()); } - protected: + private: ImmGCPtr() : value(0) {} -}; -// Used for immediates which require relocation and may be traced during minor GC. -struct ImmMaybeNurseryPtr : public ImmGCPtr -{ - explicit ImmMaybeNurseryPtr(gc::Cell *ptr) + friend class AssemblerShared; + explicit ImmGCPtr(ImmMaybeNurseryPtr ptr) : value(ptr.value) { - this->value = ptr; - MOZ_ASSERT(!IsPoisonedPtr(ptr)); + MOZ_ASSERT(!IsPoisonedPtr(ptr.value)); // asm.js shouldn't be creating GC things MOZ_ASSERT(!IsCompilingAsmJS()); } }; // Pointer to be embedded as an immediate that is loaded/stored from by an // instruction. @@ -830,30 +849,49 @@ class AssemblerShared { Vector<CallSite, 0, SystemAllocPolicy> callsites_; Vector<AsmJSHeapAccess, 0, SystemAllocPolicy> asmJSHeapAccesses_; Vector<AsmJSGlobalAccess, 0, SystemAllocPolicy> asmJSGlobalAccesses_; Vector<AsmJSAbsoluteLink, 0, SystemAllocPolicy> asmJSAbsoluteLinks_; protected: bool enoughMemory_; + bool embedsNurseryPointers_; public: AssemblerShared() - : enoughMemory_(true) + : enoughMemory_(true), + embedsNurseryPointers_(false) {} void propagateOOM(bool success) { enoughMemory_ &= success; } bool oom() const { return !enoughMemory_; } + bool embedsNurseryPointers() const { + return embedsNurseryPointers_; + } + + ImmGCPtr noteMaybeNurseryPtr(ImmMaybeNurseryPtr ptr) { +#ifdef JSGC_GENERATIONAL + if (ptr.value && gc::IsInsideNursery(ptr.value)) { + // FIXME: Ideally we'd assert this in all cases, but PJS needs to + // compile IC's from off-main-thread; it will not touch + // nursery pointers, however. + MOZ_ASSERT(GetIonContext()->runtime->onMainThread()); + embedsNurseryPointers_ = true; + } +#endif + return ImmGCPtr(ptr); + } + void append(const CallSiteDesc &desc, size_t currentOffset, size_t framePushed) { // framePushed does not include sizeof(AsmJSFrame), so add it in here (see // CallSite::stackDepth). CallSite callsite(desc, currentOffset, framePushed + sizeof(AsmJSFrame)); enoughMemory_ &= callsites_.append(callsite); } CallSiteVector &&extractCallSites() { return Move(callsites_); }
--- a/js/src/jit/shared/Assembler-x86-shared.h +++ b/js/src/jit/shared/Assembler-x86-shared.h @@ -191,22 +191,16 @@ class AssemblerX86Shared : public Assemb }; Vector<CodeLabel, 0, SystemAllocPolicy> codeLabels_; Vector<RelativePatch, 8, SystemAllocPolicy> jumps_; CompactBufferWriter jumpRelocations_; CompactBufferWriter dataRelocations_; CompactBufferWriter preBarriers_; - void writeDataRelocation(const Value &val) { - if (val.isMarkable()) { - MOZ_ASSERT(static_cast<gc::Cell*>(val.toGCThing())->isTenured()); - dataRelocations_.writeUnsigned(masm.currentOffset()); - } - } void writeDataRelocation(ImmGCPtr ptr) { if (ptr.value) dataRelocations_.writeUnsigned(masm.currentOffset()); } void writePrebarrierOffset(CodeOffsetLabel label) { preBarriers_.writeUnsigned(label.offset()); }
--- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -106,16 +106,24 @@ class MacroAssemblerX64 : public MacroAs ///////////////////////////////////////////////////////////////// void call(ImmWord target) { mov(target, rax); call(rax); } void call(ImmPtr target) { call(ImmWord(uintptr_t(target.value))); } + void writeDataRelocation(const Value &val) { + if (val.isMarkable()) { + gc::Cell *cell = reinterpret_cast<gc::Cell *>(val.toGCThing()); + if (cell && gc::IsInsideNursery(cell)) + embedsNurseryPointers_ = true; + dataRelocations_.writeUnsigned(masm.currentOffset()); + } + } // Refers to the upper 32 bits of a 64-bit Value operand. // On x86_64, the upper 32 bits do not necessarily only contain the type. Operand ToUpper32(Operand base) { switch (base.kind()) { case Operand::MEM_REG_DISP: return Operand(Register::FromCode(base.base()), base.disp() + 4); @@ -489,16 +497,19 @@ class MacroAssemblerX64 : public MacroAs void cmpPtr(Register lhs, const Imm32 rhs) { cmpq(lhs, rhs); } void cmpPtr(const Operand &lhs, const ImmGCPtr rhs) { MOZ_ASSERT(!lhs.containsReg(ScratchReg)); movq(rhs, ScratchReg); cmpq(lhs, ScratchReg); } + void cmpPtr(const Operand &lhs, const ImmMaybeNurseryPtr rhs) { + cmpPtr(lhs, noteMaybeNurseryPtr(rhs)); + } void cmpPtr(const Operand &lhs, const ImmWord rhs) { if ((intptr_t)rhs.value <= INT32_MAX && (intptr_t)rhs.value >= INT32_MIN) { cmpq(lhs, Imm32((int32_t)rhs.value)); } else { mov(rhs, ScratchReg); cmpq(lhs, ScratchReg); } } @@ -718,16 +729,19 @@ class MacroAssemblerX64 : public MacroAs mov(imm, dest); } void movePtr(AsmJSImmPtr imm, Register dest) { mov(imm, dest); } void movePtr(ImmGCPtr imm, Register dest) { movq(imm, dest); } + void movePtr(ImmMaybeNurseryPtr imm, Register dest) { + movePtr(noteMaybeNurseryPtr(imm), dest); + } void loadPtr(AbsoluteAddress address, Register dest) { if (X86Assembler::isAddressImmediate(address.addr)) { movq(Operand(address), dest); } else { mov(ImmPtr(address.addr), ScratchReg); loadPtr(Address(ScratchReg, 0x0), dest); } }
--- a/js/src/jit/x86/Assembler-x86.h +++ b/js/src/jit/x86/Assembler-x86.h @@ -202,16 +202,19 @@ class Assembler : public AssemblerX86Sha void executableCopy(uint8_t *buffer); // Actual assembly emitting functions. void push(ImmGCPtr ptr) { push(Imm32(uintptr_t(ptr.value))); writeDataRelocation(ptr); } + void push(ImmMaybeNurseryPtr ptr) { + push(noteMaybeNurseryPtr(ptr)); + } void push(const ImmWord imm) { push(Imm32(imm.value)); } void push(const ImmPtr imm) { push(ImmWord(uintptr_t(imm.value))); } void push(FloatRegister src) { subl(Imm32(sizeof(double)), StackPointer); @@ -352,16 +355,19 @@ class Assembler : public AssemblerX86Sha case Operand::MEM_ADDRESS32: masm.cmpl_im(uintptr_t(imm.value), op.address()); writeDataRelocation(imm); break; default: MOZ_CRASH("unexpected operand kind"); } } + void cmpl(const Operand &op, ImmMaybeNurseryPtr imm) { + cmpl(op, noteMaybeNurseryPtr(imm)); + } void cmpl(AsmJSAbsoluteAddress lhs, Register rhs) { masm.cmpl_rm_force32(rhs.code(), (void*)-1); append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), lhs.kind())); } void jmp(ImmPtr target, Relocation::Kind reloc = Relocation::HARDCODED) { JmpSrc src = masm.jmp(); addPendingJump(src, target, reloc);
--- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -218,17 +218,17 @@ class MacroAssemblerX86 : public MacroAs void popValue(ValueOperand val) { pop(val.payloadReg()); pop(val.typeReg()); } void pushValue(const Value &val) { jsval_layout jv = JSVAL_TO_IMPL(val); push(Imm32(jv.s.tag)); if (val.isMarkable()) - push(ImmGCPtr(reinterpret_cast<gc::Cell *>(val.toGCThing()))); + push(ImmMaybeNurseryPtr(reinterpret_cast<gc::Cell *>(val.toGCThing()))); else push(Imm32(jv.s.payload.i32)); } void pushValue(JSValueType type, Register reg) { push(ImmTag(JSVAL_TYPE_TO_TAG(type))); push(reg); } void pushValue(const Address &addr) { @@ -699,16 +699,19 @@ class MacroAssemblerX86 : public MacroAs movl(imm, dest); } void movePtr(AsmJSImmPtr imm, Register dest) { mov(imm, dest); } void movePtr(ImmGCPtr imm, Register dest) { movl(imm, dest); } + void movePtr(ImmMaybeNurseryPtr imm, Register dest) { + movePtr(noteMaybeNurseryPtr(imm), dest); + } void loadPtr(const Address &address, Register dest) { movl(Operand(address), dest); } void loadPtr(const Operand &src, Register dest) { movl(src, dest); } void loadPtr(const BaseIndex &src, Register dest) { movl(Operand(src), dest);