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