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