Exemple #1
0
INLINE void Allocator::refillAllocator(BumpAllocator& allocator, size_t sizeClass)
{
    BumpRangeCache& bumpRangeCache = m_bumpRangeCaches[sizeClass];
    if (!bumpRangeCache.size())
        return refillAllocatorSlowCase(allocator, sizeClass);
    return allocator.refill(bumpRangeCache.pop());
}
Exemple #2
0
void Heap::allocateMediumBumpRanges(std::lock_guard<StaticMutex>& lock, size_t sizeClass, BumpAllocator& allocator, BumpRangeCache& rangeCache)
{
    MediumPage* page = allocateMediumPage(lock, sizeClass);
    BASSERT(!rangeCache.size());
    MediumLine* lines = page->begin();

    // Due to overlap from the previous line, the last line in the page may not be able to fit any objects.
    size_t end = MediumPage::lineCount;
    if (!m_mediumLineMetadata[sizeClass][MediumPage::lineCount - 1].objectCount)
        --end;

    // Find a free line.
    for (size_t lineNumber = 0; lineNumber < end; ++lineNumber) {
        if (lines[lineNumber].refCount(lock))
            continue;

        // In a fragmented page, some free ranges might not fit in the cache.
        if (rangeCache.size() == rangeCache.capacity()) {
            m_mediumPagesWithFreeLines[sizeClass].push(page);
            return;
        }

        LineMetadata& lineMetadata = m_mediumLineMetadata[sizeClass][lineNumber];
        char* begin = lines[lineNumber].begin() + lineMetadata.startOffset;
        unsigned short objectCount = lineMetadata.objectCount;
        lines[lineNumber].ref(lock, lineMetadata.objectCount);
        page->ref(lock);
        
        // Merge with subsequent free lines.
        while (++lineNumber < end) {
            if (lines[lineNumber].refCount(lock))
                break;

            LineMetadata& lineMetadata = m_mediumLineMetadata[sizeClass][lineNumber];
            objectCount += lineMetadata.objectCount;
            lines[lineNumber].ref(lock, lineMetadata.objectCount);
            page->ref(lock);
        }

        if (!allocator.canAllocate())
            allocator.refill({ begin, objectCount });
        else
            rangeCache.push({ begin, objectCount });
    }
}
Exemple #3
0
bool BumpAllocatorTest() {
    bool ok = true;
    BumpAllocator alloc;
    {
        alloc.setup(1024 + sizeof(size_t) * 4, 1);
        void * a = alloc.alloc(512);
        ok = ok && a != NULL;
        void * b = alloc.alloc(256);
        ok = ok && b != NULL;
        void * c = alloc.alloc(256);
        ok = ok && c != NULL;
        ok = ok && alloc.amount_free() == sizeof(size_t);
        //fprintf(stderr, "Checking free = 0 : %d\n", ok);
        alloc.free(c);
#ifdef USE_BUILTIN_ATOMICS_FOR_ALLOCATOR
        ok = ok && alloc.amount_free() == 256 + sizeof(size_t) * 2;
        //fprintf(stderr, "Checking free = 256 : %d\n", ok);
        void * d = alloc.alloc(128);
        (void)d;
        ok = ok && alloc.amount_free() == 128 + sizeof(size_t);
        //fprintf(stderr, "Checking free = 128 : %d\n", ok);
#endif
        void * e = alloc.alloc(256);
        ok = ok && e == NULL;
        //fprintf(stderr, "Checking too much allocated = NULL: %d", ok);
        alloc.teardown();
        alloc.setup(128 + sizeof(size_t) * 2, 1);
        a = alloc.alloc(127);
        b = alloc.alloc(2);
        c = alloc.alloc(1);
        ok = ok && b == NULL;
        //fprintf(stderr, "Checking new too much allocated = NULL : %d\n", ok);
        ok = ok && alloc.amount_free() == 0;
    }
    alloc.teardown();
    {
        alloc.setup(1024 + sizeof(size_t) * 8, 16);
        void * a = alloc.alloc(512);
        ok = ok && a != NULL;
        void * b = alloc.alloc(256);
        ok = ok && b != NULL;
        void * c = alloc.alloc(256);
        ok = ok && c != NULL;
        ok = ok && alloc.amount_free() == sizeof(size_t) * 2;
        //fprintf(stderr, "Checking free = 0 : %d\n", ok);
        alloc.free(c);
#ifdef USE_BUILTIN_ATOMICS_FOR_ALLOCATOR
        ok = ok && alloc.amount_free() == 256 + sizeof(size_t) * 4;
        //fprintf(stderr, "Checking free = 256 : %d\n", ok);
        void * d = alloc.alloc(128);
        (void) d;
        ok = ok && alloc.amount_free() == 128 + sizeof(size_t) * 2;
        //fprintf(stderr, "Checking free = 128 : %d\n", ok);
#endif
        void * e = alloc.alloc(256);
        ok = ok && e == NULL;
        //fprintf(stderr, "Checking too much allocated = NULL: %d", ok);
        alloc.teardown();
    }
    //fprintf(stderr, "Checking free = 0 : %d\n", ok);
    return ok;
}