1/* 2 * Copyright (C) 2009 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 31namespace JSC { 32 33ParserArena::ParserArena() 34 : m_freeableMemory(0) 35 , m_freeablePoolEnd(0) 36 , m_identifierArena(new IdentifierArena) 37{ 38} 39 40inline void* ParserArena::freeablePool() 41{ 42 ASSERT(m_freeablePoolEnd); 43 return m_freeablePoolEnd - freeablePoolSize; 44} 45 46inline void ParserArena::deallocateObjects() 47{ 48 if (m_freeablePoolEnd) 49 fastFree(freeablePool()); 50 51 size_t size = m_freeablePools.size(); 52 for (size_t i = 0; i < size; ++i) 53 fastFree(m_freeablePools[i]); 54 55 size = m_deletableObjects.size(); 56 for (size_t i = 0; i < size; ++i) { 57 ParserArenaDeletable* object = m_deletableObjects[i]; 58 object->~ParserArenaDeletable(); 59 fastFree(object); 60 } 61} 62 63ParserArena::~ParserArena() 64{ 65 deallocateObjects(); 66} 67 68bool ParserArena::contains(ParserArenaRefCounted* object) const 69{ 70 return m_refCountedObjects.find(object) != notFound; 71} 72 73ParserArenaRefCounted* ParserArena::last() const 74{ 75 return m_refCountedObjects.last().get(); 76} 77 78void ParserArena::removeLast() 79{ 80 m_refCountedObjects.removeLast(); 81} 82 83void ParserArena::reset() 84{ 85 // Since this code path is used only when parsing fails, it's not bothering to reuse 86 // any of the memory the arena allocated. We could improve that later if we want to 87 // efficiently reuse the same arena. 88 89 deallocateObjects(); 90 91 m_freeableMemory = 0; 92 m_freeablePoolEnd = 0; 93 m_identifierArena->clear(); 94 m_freeablePools.clear(); 95 m_deletableObjects.clear(); 96 m_refCountedObjects.clear(); 97} 98 99void ParserArena::allocateFreeablePool() 100{ 101 if (m_freeablePoolEnd) 102 m_freeablePools.append(freeablePool()); 103 104 char* pool = static_cast<char*>(fastMalloc(freeablePoolSize)); 105 m_freeableMemory = pool; 106 m_freeablePoolEnd = pool + freeablePoolSize; 107 ASSERT(freeablePool() == pool); 108} 109 110bool ParserArena::isEmpty() const 111{ 112 return !m_freeablePoolEnd 113 && m_identifierArena->isEmpty() 114 && m_freeablePools.isEmpty() 115 && m_deletableObjects.isEmpty() 116 && m_refCountedObjects.isEmpty(); 117} 118 119void ParserArena::derefWithArena(PassRefPtr<ParserArenaRefCounted> object) 120{ 121 m_refCountedObjects.append(object); 122} 123 124} 125