Example #1
0
size_t
ForkJoinNursery::copyObjectToTospace(JSObject *dst, JSObject *src, AllocKind dstKind)
{
    size_t srcSize = Arena::thingSize(dstKind);
    size_t movedSize = srcSize;

    // Arrays do not necessarily have the same AllocKind between src and dst.
    // We deal with this by copying elements manually, possibly re-inlining
    // them if there is adequate room inline in dst.
    if (src->is<ArrayObject>())
        srcSize = movedSize = sizeof(ObjectImpl);

    js_memcpy(dst, src, srcSize);
    movedSize += copySlotsToTospace(dst, src, dstKind);
    movedSize += copyElementsToTospace(dst, src, dstKind);

    if (src->is<TypedArrayObject>())
        dst->setPrivate(dst->fixedData(TypedArrayObject::FIXED_DATA_START));

    // The shape's list head may point into the old object.
    if (&src->shape_ == dst->shape_->listp) {
        JS_ASSERT(cx_->isThreadLocal(dst->shape_.get()));
        dst->shape_->listp = &dst->shape_;
    }

    return movedSize;
}
Example #2
0
HeapSlot *
ForkJoinNursery::reallocateSlots(JSObject *obj, HeapSlot *oldSlots,
                                 uint32_t oldCount, uint32_t newCount)
{
    if (newCount & mozilla::tl::MulOverflowMask<sizeof(HeapSlot)>::value)
        return nullptr;

    size_t oldSize = oldCount * sizeof(HeapSlot);
    size_t newSize = newCount * sizeof(HeapSlot);

    if (!isInsideNewspace(obj)) {
        JS_ASSERT_IF(oldSlots, !isInsideNewspace(oldSlots));
        return static_cast<HeapSlot *>(cx_->realloc_(oldSlots, oldSize, newSize));
    }

    if (!isInsideNewspace(oldSlots))
        return reallocateHugeSlots(oldSlots, oldSize, newSize);

    // No-op if we're shrinking, we can't make use of the freed portion.
    if (newCount < oldCount)
        return oldSlots;

    HeapSlot *newSlots = allocateSlots(obj, newCount);
    if (!newSlots)
        return nullptr;

    js_memcpy(newSlots, oldSlots, oldSize);
    return newSlots;
}
void
Ring::copyBytes(void *data, size_t size)
{
    if (size >= bufferSize())
        size = bufferSize();

    if (offset + size > bufferSize()) {
        size_t first = bufferSize() - offset;
        size_t second = size - first;
        js_memcpy(&buffer[offset], data, first);
        js_memcpy(buffer, (char *)data + first, second);
        offset = second;
    } else {
        js_memcpy(&buffer[offset], data, size);
        offset += size;
    }
}
Example #4
0
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);
}
Example #5
0
size_t
ForkJoinNursery::copySlotsToTospace(JSObject *dst, JSObject *src, AllocKind dstKind)
{
    // Fixed slots have already been copied over.
    if (!src->hasDynamicSlots())
        return 0;

    if (!isInsideFromspace(src->slots)) {
        hugeSlots[hugeSlotsFrom].remove(src->slots);
        if (!isEvacuating_)
            hugeSlots[hugeSlotsNew].put(src->slots);
        return 0;
    }

    size_t count = src->numDynamicSlots();
    dst->slots = reinterpret_cast<HeapSlot *>(allocateInTospace(count, sizeof(HeapSlot)));
    if (!dst->slots)
        CrashAtUnhandlableOOM("Failed to allocate slots while moving object.");
    js_memcpy(dst->slots, src->slots, count * sizeof(HeapSlot));
    setSlotsForwardingPointer(src->slots, dst->slots, count);
    return count * sizeof(HeapSlot);
}