1/* 2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "ParserArena.h" 28 29#include "Nodes.h" 30#include "JSCInlines.h" 31#include <wtf/PassOwnPtr.h> 32 33namespace JSC { 34 35ParserArena::ParserArena() 36 : m_freeableMemory(0) 37 , m_freeablePoolEnd(0) 38{ 39} 40 41inline void* ParserArena::freeablePool() 42{ 43 ASSERT(m_freeablePoolEnd); 44 return m_freeablePoolEnd - freeablePoolSize; 45} 46 47inline void ParserArena::deallocateObjects() 48{ 49 size_t size = m_deletableObjects.size(); 50 for (size_t i = 0; i < size; ++i) 51 m_deletableObjects[i]->~ParserArenaDeletable(); 52 53 if (m_freeablePoolEnd) 54 fastFree(freeablePool()); 55 56 size = m_freeablePools.size(); 57 for (size_t i = 0; i < size; ++i) 58 fastFree(m_freeablePools[i]); 59} 60 61ParserArena::~ParserArena() 62{ 63 deallocateObjects(); 64} 65 66bool ParserArena::contains(ParserArenaRefCounted* object) const 67{ 68 return m_refCountedObjects.find(object) != notFound; 69} 70 71ParserArenaRefCounted* ParserArena::last() const 72{ 73 return m_refCountedObjects.last().get(); 74} 75 76void ParserArena::removeLast() 77{ 78 m_refCountedObjects.removeLast(); 79} 80 81void ParserArena::reset() 82{ 83 // Since this code path is used only when parsing fails, it's not bothering to reuse 84 // any of the memory the arena allocated. We could improve that later if we want to 85 // efficiently reuse the same arena. 86 87 deallocateObjects(); 88 89 m_freeableMemory = 0; 90 m_freeablePoolEnd = 0; 91 if (m_identifierArena) 92 m_identifierArena->clear(); 93 m_freeablePools.clear(); 94 m_deletableObjects.clear(); 95 m_refCountedObjects.clear(); 96} 97 98void ParserArena::allocateFreeablePool() 99{ 100 if (m_freeablePoolEnd) 101 m_freeablePools.append(freeablePool()); 102 103 char* pool = static_cast<char*>(fastMalloc(freeablePoolSize)); 104 m_freeableMemory = pool; 105 m_freeablePoolEnd = pool + freeablePoolSize; 106 ASSERT(freeablePool() == pool); 107} 108 109bool ParserArena::isEmpty() const 110{ 111 return !m_freeablePoolEnd 112 && (!m_identifierArena || m_identifierArena->isEmpty()) 113 && m_freeablePools.isEmpty() 114 && m_deletableObjects.isEmpty() 115 && m_refCountedObjects.isEmpty(); 116} 117 118void ParserArena::derefWithArena(PassRefPtr<ParserArenaRefCounted> object) 119{ 120 m_refCountedObjects.append(object); 121} 122 123} 124