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 #ifndef ParserArena_h 27 #define ParserArena_h 28 29 #include "Identifier.h" 30 #include <wtf/SegmentedVector.h> 31 32 namespace JSC { 33 34 class ParserArenaDeletable; 35 class ParserArenaRefCounted; 36 37 class IdentifierArena { 38 WTF_MAKE_FAST_ALLOCATED; 39 public: 40 ALWAYS_INLINE const Identifier& makeIdentifier(JSGlobalData*, const UChar* characters, size_t length); 41 const Identifier& makeNumericIdentifier(JSGlobalData*, double number); 42 clear()43 void clear() { m_identifiers.clear(); } isEmpty()44 bool isEmpty() const { return m_identifiers.isEmpty(); } 45 46 private: 47 typedef SegmentedVector<Identifier, 64> IdentifierVector; 48 IdentifierVector m_identifiers; 49 }; 50 makeIdentifier(JSGlobalData * globalData,const UChar * characters,size_t length)51 ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifier(JSGlobalData* globalData, const UChar* characters, size_t length) 52 { 53 m_identifiers.append(Identifier(globalData, characters, length)); 54 return m_identifiers.last(); 55 } 56 makeNumericIdentifier(JSGlobalData * globalData,double number)57 inline const Identifier& IdentifierArena::makeNumericIdentifier(JSGlobalData* globalData, double number) 58 { 59 m_identifiers.append(Identifier(globalData, UString::number(number))); 60 return m_identifiers.last(); 61 } 62 63 class ParserArena { 64 WTF_MAKE_NONCOPYABLE(ParserArena); 65 public: 66 ParserArena(); 67 ~ParserArena(); 68 swap(ParserArena & otherArena)69 void swap(ParserArena& otherArena) 70 { 71 std::swap(m_freeableMemory, otherArena.m_freeableMemory); 72 std::swap(m_freeablePoolEnd, otherArena.m_freeablePoolEnd); 73 m_identifierArena.swap(otherArena.m_identifierArena); 74 m_freeablePools.swap(otherArena.m_freeablePools); 75 m_deletableObjects.swap(otherArena.m_deletableObjects); 76 m_refCountedObjects.swap(otherArena.m_refCountedObjects); 77 } 78 allocateFreeable(size_t size)79 void* allocateFreeable(size_t size) 80 { 81 ASSERT(size); 82 ASSERT(size <= freeablePoolSize); 83 size_t alignedSize = alignSize(size); 84 ASSERT(alignedSize <= freeablePoolSize); 85 if (UNLIKELY(static_cast<size_t>(m_freeablePoolEnd - m_freeableMemory) < alignedSize)) 86 allocateFreeablePool(); 87 void* block = m_freeableMemory; 88 m_freeableMemory += alignedSize; 89 return block; 90 } 91 allocateDeletable(size_t size)92 void* allocateDeletable(size_t size) 93 { 94 ParserArenaDeletable* deletable = static_cast<ParserArenaDeletable*>(fastMalloc(size)); 95 m_deletableObjects.append(deletable); 96 return deletable; 97 } 98 99 void derefWithArena(PassRefPtr<ParserArenaRefCounted>); 100 bool contains(ParserArenaRefCounted*) const; 101 ParserArenaRefCounted* last() const; 102 void removeLast(); 103 104 bool isEmpty() const; 105 void reset(); 106 identifierArena()107 IdentifierArena& identifierArena() { return *m_identifierArena; } 108 109 private: 110 static const size_t freeablePoolSize = 8000; 111 alignSize(size_t size)112 static size_t alignSize(size_t size) 113 { 114 return (size + sizeof(WTF::AllocAlignmentInteger) - 1) & ~(sizeof(WTF::AllocAlignmentInteger) - 1); 115 } 116 117 void* freeablePool(); 118 void allocateFreeablePool(); 119 void deallocateObjects(); 120 121 char* m_freeableMemory; 122 char* m_freeablePoolEnd; 123 124 OwnPtr<IdentifierArena> m_identifierArena; 125 Vector<void*> m_freeablePools; 126 Vector<ParserArenaDeletable*> m_deletableObjects; 127 Vector<RefPtr<ParserArenaRefCounted> > m_refCountedObjects; 128 }; 129 130 } 131 132 #endif 133