• 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 #include "config.h"
27 #include "ParserArena.h"
28 
29 #include "Nodes.h"
30 
31 namespace JSC {
32 
ParserArena()33 ParserArena::ParserArena()
34     : m_freeableMemory(0)
35     , m_freeablePoolEnd(0)
36     , m_identifierArena(new IdentifierArena)
37 {
38 }
39 
freeablePool()40 inline void* ParserArena::freeablePool()
41 {
42     ASSERT(m_freeablePoolEnd);
43     return m_freeablePoolEnd - freeablePoolSize;
44 }
45 
deallocateObjects()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 
~ParserArena()63 ParserArena::~ParserArena()
64 {
65     deallocateObjects();
66 }
67 
contains(ParserArenaRefCounted * object) const68 bool ParserArena::contains(ParserArenaRefCounted* object) const
69 {
70     return m_refCountedObjects.find(object) != notFound;
71 }
72 
last() const73 ParserArenaRefCounted* ParserArena::last() const
74 {
75     return m_refCountedObjects.last().get();
76 }
77 
removeLast()78 void ParserArena::removeLast()
79 {
80     m_refCountedObjects.removeLast();
81 }
82 
reset()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 
allocateFreeablePool()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 
isEmpty() const110 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 
derefWithArena(PassRefPtr<ParserArenaRefCounted> object)119 void ParserArena::derefWithArena(PassRefPtr<ParserArenaRefCounted> object)
120 {
121     m_refCountedObjects.append(object);
122 }
123 
124 }
125