]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/ArgList.h
JavaScriptCore-554.1.tar.gz
[apple/javascriptcore.git] / runtime / ArgList.h
1 /*
2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3 * Copyright (C) 2003, 2007, 2008, 2009 Apple Computer, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22 #ifndef ArgList_h
23 #define ArgList_h
24
25 #include "Register.h"
26
27 #include <wtf/HashSet.h>
28 #include <wtf/Noncopyable.h>
29 #include <wtf/Vector.h>
30
31 namespace JSC {
32
33 class MarkedArgumentBuffer : Noncopyable {
34 private:
35 static const unsigned inlineCapacity = 8;
36 typedef Vector<Register, inlineCapacity> VectorType;
37 typedef HashSet<MarkedArgumentBuffer*> ListSet;
38
39 public:
40 typedef VectorType::iterator iterator;
41 typedef VectorType::const_iterator const_iterator;
42
43 // Constructor for a read-write list, to which you may append values.
44 // FIXME: Remove all clients of this API, then remove this API.
45 MarkedArgumentBuffer()
46 : m_isUsingInlineBuffer(true)
47 , m_markSet(0)
48 #ifndef NDEBUG
49 , m_isReadOnly(false)
50 #endif
51 {
52 m_buffer = m_vector.data();
53 m_size = 0;
54 }
55
56 // Constructor for a read-only list whose data has already been allocated elsewhere.
57 MarkedArgumentBuffer(Register* buffer, size_t size)
58 : m_buffer(buffer)
59 , m_size(size)
60 , m_isUsingInlineBuffer(true)
61 , m_markSet(0)
62 #ifndef NDEBUG
63 , m_isReadOnly(true)
64 #endif
65 {
66 }
67
68 void initialize(Register* buffer, size_t size)
69 {
70 ASSERT(!m_markSet);
71 ASSERT(isEmpty());
72
73 m_buffer = buffer;
74 m_size = size;
75 #ifndef NDEBUG
76 m_isReadOnly = true;
77 #endif
78 }
79
80 ~MarkedArgumentBuffer()
81 {
82 if (m_markSet)
83 m_markSet->remove(this);
84 }
85
86 size_t size() const { return m_size; }
87 bool isEmpty() const { return !m_size; }
88
89 JSValue at(size_t i) const
90 {
91 if (i < m_size)
92 return m_buffer[i].jsValue();
93 return jsUndefined();
94 }
95
96 void clear()
97 {
98 m_vector.clear();
99 m_buffer = 0;
100 m_size = 0;
101 }
102
103 void append(JSValue v)
104 {
105 ASSERT(!m_isReadOnly);
106
107 if (m_isUsingInlineBuffer && m_size < inlineCapacity) {
108 m_vector.uncheckedAppend(v);
109 ++m_size;
110 } else {
111 // Putting this case all in one function measurably improves
112 // the performance of the fast "just append to inline buffer" case.
113 slowAppend(v);
114 ++m_size;
115 m_isUsingInlineBuffer = false;
116 }
117 }
118
119 void removeLast()
120 {
121 ASSERT(m_size);
122 m_size--;
123 m_vector.removeLast();
124 }
125
126 JSValue last()
127 {
128 ASSERT(m_size);
129 return m_buffer[m_size - 1].jsValue();
130 }
131
132 iterator begin() { return m_buffer; }
133 iterator end() { return m_buffer + m_size; }
134
135 const_iterator begin() const { return m_buffer; }
136 const_iterator end() const { return m_buffer + m_size; }
137
138 static void markLists(ListSet&);
139
140 private:
141 void slowAppend(JSValue);
142
143 Register* m_buffer;
144 size_t m_size;
145 bool m_isUsingInlineBuffer;
146
147 VectorType m_vector;
148 ListSet* m_markSet;
149 #ifndef NDEBUG
150 bool m_isReadOnly;
151 #endif
152
153 private:
154 // Prohibits new / delete, which would break GC.
155 friend class JSGlobalData;
156
157 void* operator new(size_t size)
158 {
159 return fastMalloc(size);
160 }
161 void operator delete(void* p)
162 {
163 fastFree(p);
164 }
165
166 void* operator new[](size_t);
167 void operator delete[](void*);
168
169 void* operator new(size_t, void*);
170 void operator delete(void*, size_t);
171 };
172
173 class ArgList {
174 friend class JIT;
175 public:
176 typedef JSValue* iterator;
177 typedef const JSValue* const_iterator;
178
179 ArgList()
180 : m_args(0)
181 , m_argCount(0)
182 {
183 }
184
185 ArgList(JSValue* args, unsigned argCount)
186 : m_args(args)
187 , m_argCount(argCount)
188 {
189 }
190
191 ArgList(Register* args, int argCount)
192 : m_args(reinterpret_cast<JSValue*>(args))
193 , m_argCount(argCount)
194 {
195 ASSERT(argCount >= 0);
196 }
197
198 ArgList(const MarkedArgumentBuffer& args)
199 : m_args(reinterpret_cast<JSValue*>(const_cast<Register*>(args.begin())))
200 , m_argCount(args.size())
201 {
202 }
203
204 JSValue at(size_t idx) const
205 {
206 if (idx < m_argCount)
207 return m_args[idx];
208 return jsUndefined();
209 }
210
211 bool isEmpty() const { return !m_argCount; }
212
213 size_t size() const { return m_argCount; }
214
215 iterator begin() { return m_args; }
216 iterator end() { return m_args + m_argCount; }
217
218 const_iterator begin() const { return m_args; }
219 const_iterator end() const { return m_args + m_argCount; }
220
221 void getSlice(int startIndex, ArgList& result) const;
222 private:
223 JSValue* m_args;
224 size_t m_argCount;
225 };
226
227 } // namespace JSC
228
229 #endif // ArgList_h