2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3 * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved.
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.
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.
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.
25 #include "CallFrame.h"
27 #include "WriteBarrier.h"
28 #include <wtf/HashSet.h>
29 #include <wtf/Vector.h>
35 class MarkedArgumentBuffer {
36 WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer);
38 static const unsigned inlineCapacity = 8;
39 typedef Vector<Register, inlineCapacity> VectorType;
40 typedef HashSet<MarkedArgumentBuffer*> ListSet;
43 typedef VectorType::iterator iterator;
44 typedef VectorType::const_iterator const_iterator;
46 // Constructor for a read-write list, to which you may append values.
47 // FIXME: Remove all clients of this API, then remove this API.
48 MarkedArgumentBuffer()
49 : m_isUsingInlineBuffer(true)
55 m_buffer = m_vector.data();
59 // Constructor for a read-only list whose data has already been allocated elsewhere.
60 MarkedArgumentBuffer(Register* buffer, size_t size)
63 , m_isUsingInlineBuffer(true)
71 void initialize(WriteBarrier<Unknown>* buffer, size_t size)
76 m_buffer = reinterpret_cast<Register*>(buffer);
83 ~MarkedArgumentBuffer()
86 m_markSet->remove(this);
89 size_t size() const { return m_size; }
90 bool isEmpty() const { return !m_size; }
92 JSValue at(size_t i) const
95 return m_buffer[i].jsValue();
106 void append(JSValue v)
108 ASSERT(!m_isReadOnly);
110 if (m_isUsingInlineBuffer && m_size < inlineCapacity) {
111 m_vector.uncheckedAppend(v);
114 // Putting this case all in one function measurably improves
115 // the performance of the fast "just append to inline buffer" case.
118 m_isUsingInlineBuffer = false;
126 m_vector.removeLast();
132 return m_buffer[m_size - 1].jsValue();
135 iterator begin() { return m_buffer; }
136 iterator end() { return m_buffer + m_size; }
138 const_iterator begin() const { return m_buffer; }
139 const_iterator end() const { return m_buffer + m_size; }
141 static void markLists(HeapRootVisitor&, ListSet&);
144 void slowAppend(JSValue);
148 bool m_isUsingInlineBuffer;
157 // Prohibits new / delete, which would break GC.
158 friend class JSGlobalData;
160 void* operator new(size_t size)
162 return fastMalloc(size);
164 void operator delete(void* p)
169 void* operator new[](size_t);
170 void operator delete[](void*);
172 void* operator new(size_t, void*);
173 void operator delete(void*, size_t);
179 typedef JSValue* iterator;
180 typedef const JSValue* const_iterator;
188 ArgList(ExecState* exec)
189 : m_args(reinterpret_cast<JSValue*>(&exec[exec->hostThisRegister() + 1]))
190 , m_argCount(exec->argumentCount())
194 ArgList(JSValue* args, unsigned argCount)
196 , m_argCount(argCount)
200 ArgList(Register* args, int argCount)
201 : m_args(reinterpret_cast<JSValue*>(args))
202 , m_argCount(argCount)
204 ASSERT(argCount >= 0);
207 ArgList(const MarkedArgumentBuffer& args)
208 : m_args(reinterpret_cast<JSValue*>(const_cast<Register*>(args.begin())))
209 , m_argCount(args.size())
213 JSValue at(size_t idx) const
215 if (idx < m_argCount)
217 return jsUndefined();
220 bool isEmpty() const { return !m_argCount; }
222 size_t size() const { return m_argCount; }
224 iterator begin() { return m_args; }
225 iterator end() { return m_args + m_argCount; }
227 const_iterator begin() const { return m_args; }
228 const_iterator end() const { return m_args + m_argCount; }
230 void getSlice(int startIndex, ArgList& result) const;