/*
 * Copyright (C) 2003 Apple Computer, Inc.
 *
 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Alternatively, the contents of this file may be used under the terms
 * of either the Mozilla Public License Version 1.1, found at
 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
 * (the "GPL"), in which case the provisions of the MPL or the GPL are
 * applicable instead of those above.  If you wish to allow use of your
 * version of this file only under the terms of one of those two
 * licenses (the MPL or the GPL) and not to allow others to use your
 * version of this file under the LGPL, indicate your decision by
 * deletingthe provisions above and replace them with the notice and
 * other provisions required by the MPL or the GPL, as the case may be.
 * If you do not delete the provisions above, a recipient may use your
 * version of this file under any of the LGPL, the MPL or the GPL.
 */

#include "config.h"
#include "RenderArena.h"

#include <stdlib.h>
#include <string.h>
#include <wtf/Assertions.h>

#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))

namespace WebCore {

#ifndef NDEBUG

const int signature = 0xDBA00AEA;
const int signatureDead = 0xDBA00AED;

typedef struct {
    RenderArena* arena;
    size_t size;
    int signature;
} RenderArenaDebugHeader;

#endif

RenderArena::RenderArena(unsigned arenaSize)
{
    // Initialize the arena pool
    INIT_ARENA_POOL(&m_pool, "RenderArena", arenaSize);

    // Zero out the recyclers array
    memset(m_recyclers, 0, sizeof(m_recyclers));
}

RenderArena::~RenderArena()
{
    FinishArenaPool(&m_pool);
}

void* RenderArena::allocate(size_t size)
{
#ifndef NDEBUG
    // Use standard malloc so that memory debugging tools work.
    ASSERT(this);
    void* block = ::malloc(sizeof(RenderArenaDebugHeader) + size);
    RenderArenaDebugHeader* header = static_cast<RenderArenaDebugHeader*>(block);
    header->arena = this;
    header->size = size;
    header->signature = signature;
    return header + 1;
#else
    void* result = 0;

    // Ensure we have correct alignment for pointers.  Important for Tru64
    size = ROUNDUP(size, sizeof(void*));

    // Check recyclers first
    if (size < gMaxRecycledSize) {
        const int index = size >> 2;

        result = m_recyclers[index];
        if (result) {
            // Need to move to the next object
            void* next = *((void**)result);
            m_recyclers[index] = next;
        }
    }

    if (!result) {
        // Allocate a new chunk from the arena
        ARENA_ALLOCATE(result, &m_pool, size);
    }

    return result;
#endif
}

void RenderArena::free(size_t size, void* ptr)
{
#ifndef NDEBUG
    // Use standard free so that memory debugging tools work.
    RenderArenaDebugHeader* header = static_cast<RenderArenaDebugHeader*>(ptr) - 1;
    ASSERT(header->signature == signature);
    ASSERT(header->size == size);
    ASSERT(header->arena == this);
    header->signature = signatureDead;
    ::free(header);
#else
    // Ensure we have correct alignment for pointers.  Important for Tru64
    size = ROUNDUP(size, sizeof(void*));

    // See if it's a size that we recycle
    if (size < gMaxRecycledSize) {
        const int index = size >> 2;
        void* currentTop = m_recyclers[index];
        m_recyclers[index] = ptr;
        *((void**)ptr) = currentTop;
    }
#endif
}

} // namespace WebCore
