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>
34 typedef MarkStack SlotVisitor
;
36 class MarkedArgumentBuffer
{
37 WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer
);
39 static const unsigned inlineCapacity
= 8;
40 typedef Vector
<Register
, inlineCapacity
> VectorType
;
41 typedef HashSet
<MarkedArgumentBuffer
*> ListSet
;
44 typedef VectorType::iterator iterator
;
45 typedef VectorType::const_iterator const_iterator
;
47 // Constructor for a read-write list, to which you may append values.
48 // FIXME: Remove all clients of this API, then remove this API.
49 MarkedArgumentBuffer()
50 : m_isUsingInlineBuffer(true)
56 m_buffer
= m_vector
.data();
60 // Constructor for a read-only list whose data has already been allocated elsewhere.
61 MarkedArgumentBuffer(Register
* buffer
, size_t size
)
64 , m_isUsingInlineBuffer(true)
72 void initialize(WriteBarrier
<Unknown
>* buffer
, size_t size
)
77 m_buffer
= reinterpret_cast<Register
*>(buffer
);
84 ~MarkedArgumentBuffer()
87 m_markSet
->remove(this);
90 size_t size() const { return m_size
; }
91 bool isEmpty() const { return !m_size
; }
93 JSValue
at(size_t i
) const
96 return m_buffer
[i
].jsValue();
107 void append(JSValue v
)
109 ASSERT(!m_isReadOnly
);
111 #if ENABLE(JSC_ZOMBIES)
112 ASSERT(!v
.isZombie());
115 if (m_isUsingInlineBuffer
&& m_size
< inlineCapacity
) {
116 m_vector
.uncheckedAppend(v
);
119 // Putting this case all in one function measurably improves
120 // the performance of the fast "just append to inline buffer" case.
123 m_isUsingInlineBuffer
= false;
131 m_vector
.removeLast();
137 return m_buffer
[m_size
- 1].jsValue();
140 iterator
begin() { return m_buffer
; }
141 iterator
end() { return m_buffer
+ m_size
; }
143 const_iterator
begin() const { return m_buffer
; }
144 const_iterator
end() const { return m_buffer
+ m_size
; }
146 static void markLists(HeapRootVisitor
&, ListSet
&);
149 void slowAppend(JSValue
);
153 bool m_isUsingInlineBuffer
;
162 // Prohibits new / delete, which would break GC.
163 friend class JSGlobalData
;
165 void* operator new(size_t size
)
167 return fastMalloc(size
);
169 void operator delete(void* p
)
174 void* operator new[](size_t);
175 void operator delete[](void*);
177 void* operator new(size_t, void*);
178 void operator delete(void*, size_t);
184 typedef JSValue
* iterator
;
185 typedef const JSValue
* const_iterator
;
193 ArgList(ExecState
* exec
)
194 : m_args(reinterpret_cast<JSValue
*>(&exec
[exec
->hostThisRegister() + 1]))
195 , m_argCount(exec
->argumentCount())
199 ArgList(JSValue
* args
, unsigned argCount
)
201 , m_argCount(argCount
)
203 #if ENABLE(JSC_ZOMBIES)
204 for (size_t i
= 0; i
< argCount
; i
++)
205 ASSERT(!m_args
[i
].isZombie());
209 ArgList(Register
* args
, int argCount
)
210 : m_args(reinterpret_cast<JSValue
*>(args
))
211 , m_argCount(argCount
)
213 ASSERT(argCount
>= 0);
216 ArgList(const MarkedArgumentBuffer
& args
)
217 : m_args(reinterpret_cast<JSValue
*>(const_cast<Register
*>(args
.begin())))
218 , m_argCount(args
.size())
222 JSValue
at(size_t idx
) const
224 if (idx
< m_argCount
)
226 return jsUndefined();
229 bool isEmpty() const { return !m_argCount
; }
231 size_t size() const { return m_argCount
; }
233 iterator
begin() { return m_args
; }
234 iterator
end() { return m_args
+ m_argCount
; }
236 const_iterator
begin() const { return m_args
; }
237 const_iterator
end() const { return m_args
+ m_argCount
; }
239 void getSlice(int startIndex
, ArgList
& result
) const;