diff --git a/js/src/jit/BaselineCacheIRCompiler.cpp b/js/src/jit/BaselineCacheIRCompiler.cpp index 11d978dece82..de4d522d5b47 100644 --- a/js/src/jit/BaselineCacheIRCompiler.cpp +++ b/js/src/jit/BaselineCacheIRCompiler.cpp @@ -3716,9 +3716,9 @@ bool BaselineCacheIRCompiler::emitNewArrayObjectResult(uint32_t arrayLength, Label done; Label fail; - masm.createArrayWithFixedElements(result, shape, scratch, arrayLength, - arrayCapacity, allocKind, gc::Heap::Default, - &fail, AllocSiteInput(site)); + masm.createArrayWithFixedElements( + result, shape, scratch, InvalidReg, arrayLength, arrayCapacity, 0, 0, + allocKind, gc::Heap::Default, &fail, AllocSiteInput(site)); masm.jump(&done); { diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 1e98d564ba4e..d6d1eec9eaf8 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -7902,8 +7902,8 @@ void CodeGenerator::visitNewArrayObject(LNewArrayObject* lir) { masm.movePtr(ImmPtr(shape), shapeReg); masm.createArrayWithFixedElements( - objReg, shapeReg, temp0Reg, arrayLength, arrayCapacity, allocKind, - mir->initialHeap(), ool->entry(), + objReg, shapeReg, temp0Reg, InvalidReg, arrayLength, arrayCapacity, 0, 0, + allocKind, mir->initialHeap(), ool->entry(), AllocSiteInput(gc::CatchAllAllocSite::Optimized)); masm.bind(ool->rejoin()); } @@ -13752,9 +13752,9 @@ void CodeGenerator::visitRest(LRest* lir) { Label joinAlloc, failAlloc; masm.movePtr(ImmGCPtr(shape), temp0); - masm.createArrayWithFixedElements(temp2, temp0, temp1, arrayLength, - arrayCapacity, allocKind, - gc::Heap::Default, &failAlloc); + masm.createArrayWithFixedElements(temp2, temp0, temp1, InvalidReg, + arrayLength, arrayCapacity, 0, 0, + allocKind, gc::Heap::Default, &failAlloc); masm.jump(&joinAlloc); { masm.bind(&failAlloc); diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index f9078beb0243..bb76f1570fe2 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -496,28 +496,35 @@ void MacroAssembler::createPlainGCObject( } void MacroAssembler::createArrayWithFixedElements( - Register result, Register shape, Register temp, uint32_t arrayLength, - uint32_t arrayCapacity, gc::AllocKind allocKind, gc::Heap initialHeap, + Register result, Register shape, Register temp, Register dynamicSlotsTemp, + uint32_t arrayLength, uint32_t arrayCapacity, uint32_t numUsedDynamicSlots, + uint32_t numDynamicSlots, gc::AllocKind allocKind, gc::Heap initialHeap, Label* fail, const AllocSiteInput& allocSite) { MOZ_ASSERT(gc::IsObjectAllocKind(allocKind)); MOZ_ASSERT(shape != temp, "shape can overlap with temp2, but not temp"); MOZ_ASSERT(result != temp); // This only supports allocating arrays with fixed elements and does not - // support any dynamic slots or elements. + // support any dynamic elements. MOZ_ASSERT(arrayCapacity >= arrayLength); MOZ_ASSERT(gc::GetGCKindSlots(allocKind) >= arrayCapacity + ObjectElements::VALUES_PER_HEADER); + MOZ_ASSERT(numUsedDynamicSlots <= numDynamicSlots); + // Allocate object. - allocateObject(result, temp, allocKind, 0, initialHeap, fail, allocSite); + allocateObject(result, temp, allocKind, numDynamicSlots, initialHeap, fail, + allocSite); // Initialize shape field. storePtr(shape, Address(result, JSObject::offsetOfShape())); - // There are no dynamic slots. - storePtr(ImmPtr(emptyObjectSlots), - Address(result, NativeObject::offsetOfSlots())); + // If the object has dynamic slots, allocateObject will initialize + // the slots field. If not, we must initialize it now. + if (numDynamicSlots == 0) { + storePtr(ImmPtr(emptyObjectSlots), + Address(result, NativeObject::offsetOfSlots())); + } // Initialize elements pointer for fixed (inline) elements. computeEffectiveAddress( @@ -531,6 +538,15 @@ void MacroAssembler::createArrayWithFixedElements( store32(Imm32(arrayCapacity), Address(temp, ObjectElements::offsetOfCapacity())); store32(Imm32(arrayLength), Address(temp, ObjectElements::offsetOfLength())); + + // Initialize dynamic slots. + if (numUsedDynamicSlots > 0) { + MOZ_ASSERT(dynamicSlotsTemp != temp); + MOZ_ASSERT(dynamicSlotsTemp != InvalidReg); + loadPtr(Address(result, NativeObject::offsetOfSlots()), dynamicSlotsTemp); + fillSlotsWithUndefined(Address(dynamicSlotsTemp, 0), temp, 0, + numUsedDynamicSlots); + } } // Inline version of Nursery::allocateString. diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 2fef1ad1dbe2..d326a0dbd6b2 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -5229,10 +5229,14 @@ class MacroAssembler : public MacroAssemblerSpecific { const AllocSiteInput& allocSite, bool initContents = true); + // dynamicSlotsTemp is used to initialize the dynamic slots after allocating + // the object. If numUsedDynamicSlots == 0, it may be InvalidReg. void createArrayWithFixedElements( - Register result, Register shape, Register temp, uint32_t arrayLength, - uint32_t arrayCapacity, gc::AllocKind allocKind, gc::Heap initialHeap, - Label* fail, const AllocSiteInput& allocSite = AllocSiteInput()); + Register result, Register shape, Register temp, Register dynamicSlotsTemp, + uint32_t arrayLength, uint32_t arrayCapacity, + uint32_t numUsedDynamicSlots, uint32_t numDynamicSlots, + gc::AllocKind allocKind, gc::Heap initialHeap, Label* fail, + const AllocSiteInput& allocSite = AllocSiteInput()); void initGCThing(Register obj, Register temp, const TemplateObject& templateObj, bool initContents = true);