size_t js::Nursery::moveElementsToTenured(JSObject *dst, JSObject *src, AllocKind dstKind) { if (src->hasEmptyElements()) return 0; Zone *zone = src->zone(); ObjectElements *srcHeader = src->getElementsHeader(); ObjectElements *dstHeader; /* TODO Bug 874151: Prefer to put element data inline if we have space. */ if (!isInside(srcHeader)) { JS_ASSERT(src->elements == dst->elements); hugeSlots.remove(reinterpret_cast<HeapSlot*>(srcHeader)); return 0; } /* ArrayBuffer stores byte-length, not Value count. */ if (src->is<ArrayBufferObject>()) { size_t nbytes; if (src->hasDynamicElements()) { nbytes = sizeof(ObjectElements) + srcHeader->initializedLength; dstHeader = static_cast<ObjectElements *>(zone->malloc_(nbytes)); if (!dstHeader) CrashAtUnhandlableOOM("Failed to allocate array buffer elements while tenuring."); } else { dst->setFixedElements(); nbytes = GetGCKindSlots(dst->tenuredGetAllocKind()) * sizeof(HeapSlot); dstHeader = dst->getElementsHeader(); } js_memcpy(dstHeader, srcHeader, nbytes); setElementsForwardingPointer(srcHeader, dstHeader, nbytes / sizeof(HeapSlot)); dst->elements = dstHeader->elements(); return src->hasDynamicElements() ? nbytes : 0; } size_t nslots = ObjectElements::VALUES_PER_HEADER + srcHeader->capacity; /* Unlike other objects, Arrays can have fixed elements. */ if (src->is<ArrayObject>() && nslots <= GetGCKindSlots(dstKind)) { dst->setFixedElements(); dstHeader = dst->getElementsHeader(); js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot)); setElementsForwardingPointer(srcHeader, dstHeader, nslots); return nslots * sizeof(HeapSlot); } JS_ASSERT(nslots >= 2); size_t nbytes = nslots * sizeof(HeapValue); dstHeader = static_cast<ObjectElements *>(zone->malloc_(nbytes)); if (!dstHeader) CrashAtUnhandlableOOM("Failed to allocate elements while tenuring."); js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot)); setElementsForwardingPointer(srcHeader, dstHeader, nslots); dst->elements = dstHeader->elements(); return nslots * sizeof(HeapSlot); }
void js::Nursery::moveElementsToTenured(JSObject *dst, JSObject *src, AllocKind dstKind) { if (src->hasEmptyElements()) return; Allocator *alloc = &src->zone()->allocator; ObjectElements *srcHeader = src->getElementsHeader(); ObjectElements *dstHeader; if (!isInside(srcHeader)) { JS_ASSERT(src->elements == dst->elements); hugeSlots.remove(reinterpret_cast<HeapSlot*>(srcHeader)); return; } /* ArrayBuffer stores byte-length, not Value count. */ if (src->isArrayBuffer()) { size_t nbytes = sizeof(ObjectElements) + srcHeader->initializedLength; if (src->hasDynamicElements()) { dstHeader = static_cast<ObjectElements *>(alloc->malloc_(nbytes)); if (!dstHeader) MOZ_CRASH(); } else { dst->setFixedElements(); dstHeader = dst->getElementsHeader(); } js_memcpy(dstHeader, srcHeader, nbytes); dst->elements = dstHeader->elements(); return; } size_t nslots = ObjectElements::VALUES_PER_HEADER + srcHeader->initializedLength; /* Unlike other objects, Arrays can have fixed elements. */ if (src->isArray() && nslots <= GetGCKindSlots(dstKind)) { dst->setFixedElements(); dstHeader = dst->getElementsHeader(); js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot)); dstHeader->capacity = GetGCKindSlots(dstKind) - ObjectElements::VALUES_PER_HEADER; return; } size_t nbytes = nslots * sizeof(HeapValue); dstHeader = static_cast<ObjectElements *>(alloc->malloc_(nbytes)); if (!dstHeader) MOZ_CRASH(); js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot)); dstHeader->capacity = srcHeader->initializedLength; dst->elements = dstHeader->elements(); }
size_t ForkJoinNursery::copyElementsToTospace(JSObject *dst, JSObject *src, AllocKind dstKind) { if (src->hasEmptyElements()) return 0; ObjectElements *srcHeader = src->getElementsHeader(); ObjectElements *dstHeader; // TODO Bug 874151: Prefer to put element data inline if we have space. // (Note, not a correctness issue.) if (!isInsideFromspace(srcHeader)) { JS_ASSERT(src->elements == dst->elements); hugeSlots[hugeSlotsFrom].remove(reinterpret_cast<HeapSlot*>(srcHeader)); if (!isEvacuating_) hugeSlots[hugeSlotsNew].put(reinterpret_cast<HeapSlot*>(srcHeader)); return 0; } size_t nslots = ObjectElements::VALUES_PER_HEADER + srcHeader->capacity; // Unlike other objects, Arrays can have fixed elements. if (src->is<ArrayObject>() && nslots <= GetGCKindSlots(dstKind)) { dst->setFixedElements(); dstHeader = dst->getElementsHeader(); js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot)); setElementsForwardingPointer(srcHeader, dstHeader, nslots); return nslots * sizeof(HeapSlot); } JS_ASSERT(nslots >= 2); dstHeader = reinterpret_cast<ObjectElements *>(allocateInTospace(nslots, sizeof(HeapSlot))); if (!dstHeader) CrashAtUnhandlableOOM("Failed to allocate elements while moving object."); js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot)); setElementsForwardingPointer(srcHeader, dstHeader, nslots); dst->elements = dstHeader->elements(); return nslots * sizeof(HeapSlot); }