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 31 namespace JSC { 32 33 ParserArena::ParserArena() 34 : m_freeableMemory(0) 35 , m_freeablePoolEnd(0) 36 , m_identifierArena(new IdentifierArena) 37 { 38 } 39 40 inline void* ParserArena::freeablePool() 41 { 42 ASSERT(m_freeablePoolEnd); 43 return m_freeablePoolEnd - freeablePoolSize; 44 } 45 46 inline 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 63 ParserArena::~ParserArena() 64 { 65 deallocateObjects(); 66 } 67 68 bool ParserArena::contains(ParserArenaRefCounted* object) const 69 { 70 return m_refCountedObjects.find(object) != notFound; 71 } 72 73 ParserArenaRefCounted* ParserArena::last() const 74 { 75 return m_refCountedObjects.last().get(); 76 } 77 78 void ParserArena::removeLast() 79 { 80 m_refCountedObjects.removeLast(); 81 } 82 83 void 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 99 void 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 110 bool 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 119 void ParserArena::derefWithArena(PassRefPtr<ParserArenaRefCounted> object) 120 { 121 m_refCountedObjects.append(object); 122 } 123 124 } 125