/*
 * Copyright (C) 2009 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "ParserArena.h"

#include "Nodes.h"

namespace JSC {

ParserArena::ParserArena()
    : m_freeableMemory(0)
    , m_freeablePoolEnd(0)
    , m_identifierArena(new IdentifierArena)
{
}

inline void* ParserArena::freeablePool()
{
    ASSERT(m_freeablePoolEnd);
    return m_freeablePoolEnd - freeablePoolSize;
}

inline void ParserArena::deallocateObjects()
{
    if (m_freeablePoolEnd)
        fastFree(freeablePool());

    size_t size = m_freeablePools.size();
    for (size_t i = 0; i < size; ++i)
        fastFree(m_freeablePools[i]);

    size = m_deletableObjects.size();
    for (size_t i = 0; i < size; ++i) {
        ParserArenaDeletable* object = m_deletableObjects[i];
        object->~ParserArenaDeletable();
        fastFree(object);
    }
}

ParserArena::~ParserArena()
{
    deallocateObjects();
}

bool ParserArena::contains(ParserArenaRefCounted* object) const
{
    return m_refCountedObjects.find(object) != notFound;
}

ParserArenaRefCounted* ParserArena::last() const
{
    return m_refCountedObjects.last().get();
}

void ParserArena::removeLast()
{
    m_refCountedObjects.removeLast();
}

void ParserArena::reset()
{
    // Since this code path is used only when parsing fails, it's not bothering to reuse
    // any of the memory the arena allocated. We could improve that later if we want to
    // efficiently reuse the same arena.

    deallocateObjects();

    m_freeableMemory = 0;
    m_freeablePoolEnd = 0;
    m_identifierArena->clear();
    m_freeablePools.clear();
    m_deletableObjects.clear();
    m_refCountedObjects.clear();
}

void ParserArena::allocateFreeablePool()
{
    if (m_freeablePoolEnd)
        m_freeablePools.append(freeablePool());

    char* pool = static_cast<char*>(fastMalloc(freeablePoolSize));
    m_freeableMemory = pool;
    m_freeablePoolEnd = pool + freeablePoolSize;
    ASSERT(freeablePool() == pool);
}

bool ParserArena::isEmpty() const
{
    return !m_freeablePoolEnd
        && m_identifierArena->isEmpty()
        && m_freeablePools.isEmpty()
        && m_deletableObjects.isEmpty()
        && m_refCountedObjects.isEmpty();
}

void ParserArena::derefWithArena(PassRefPtr<ParserArenaRefCounted> object)
{
    m_refCountedObjects.append(object);
}

}
