/* | |
* 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); | |
} | |
} |