diff -r 000000000000 -r 1918ee327afb src/3rdparty/webkit/JavaScriptCore/runtime/ArgList.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ArgList.h Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,230 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef ArgList_h +#define ArgList_h + +#include "Register.h" +#include +#include +#include + +namespace JSC { + + class MarkStack; + + class MarkedArgumentBuffer : public Noncopyable { + private: + static const unsigned inlineCapacity = 8; + typedef Vector VectorType; + typedef HashSet ListSet; + + public: + typedef VectorType::iterator iterator; + typedef VectorType::const_iterator const_iterator; + + // Constructor for a read-write list, to which you may append values. + // FIXME: Remove all clients of this API, then remove this API. + MarkedArgumentBuffer() + : m_isUsingInlineBuffer(true) + , m_markSet(0) +#ifndef NDEBUG + , m_isReadOnly(false) +#endif + { + m_buffer = m_vector.data(); + m_size = 0; + } + + // Constructor for a read-only list whose data has already been allocated elsewhere. + MarkedArgumentBuffer(Register* buffer, size_t size) + : m_buffer(buffer) + , m_size(size) + , m_isUsingInlineBuffer(true) + , m_markSet(0) +#ifndef NDEBUG + , m_isReadOnly(true) +#endif + { + } + + void initialize(Register* buffer, size_t size) + { + ASSERT(!m_markSet); + ASSERT(isEmpty()); + + m_buffer = buffer; + m_size = size; +#ifndef NDEBUG + m_isReadOnly = true; +#endif + } + + ~MarkedArgumentBuffer() + { + if (m_markSet) + m_markSet->remove(this); + } + + size_t size() const { return m_size; } + bool isEmpty() const { return !m_size; } + + JSValue at(size_t i) const + { + if (i < m_size) + return m_buffer[i].jsValue(); + return jsUndefined(); + } + + void clear() + { + m_vector.clear(); + m_buffer = 0; + m_size = 0; + } + + void append(JSValue v) + { + ASSERT(!m_isReadOnly); + + if (m_isUsingInlineBuffer && m_size < inlineCapacity) { + m_vector.uncheckedAppend(v); + ++m_size; + } else { + // Putting this case all in one function measurably improves + // the performance of the fast "just append to inline buffer" case. + slowAppend(v); + ++m_size; + m_isUsingInlineBuffer = false; + } + } + + void removeLast() + { + ASSERT(m_size); + m_size--; + m_vector.removeLast(); + } + + JSValue last() + { + ASSERT(m_size); + return m_buffer[m_size - 1].jsValue(); + } + + iterator begin() { return m_buffer; } + iterator end() { return m_buffer + m_size; } + + const_iterator begin() const { return m_buffer; } + const_iterator end() const { return m_buffer + m_size; } + + static void markLists(MarkStack&, ListSet&); + + private: + void slowAppend(JSValue); + + Register* m_buffer; + size_t m_size; + bool m_isUsingInlineBuffer; + + VectorType m_vector; + ListSet* m_markSet; +#ifndef NDEBUG + bool m_isReadOnly; +#endif + + private: + // Prohibits new / delete, which would break GC. + friend class JSGlobalData; + + void* operator new(size_t size) + { + return fastMalloc(size); + } + void operator delete(void* p) + { + fastFree(p); + } + + void* operator new[](size_t); + void operator delete[](void*); + + void* operator new(size_t, void*); + void operator delete(void*, size_t); + }; + + class ArgList { + friend class JIT; + public: + typedef JSValue* iterator; + typedef const JSValue* const_iterator; + + ArgList() + : m_args(0) + , m_argCount(0) + { + } + + ArgList(JSValue* args, unsigned argCount) + : m_args(args) + , m_argCount(argCount) + { + } + + ArgList(Register* args, int argCount) + : m_args(reinterpret_cast(args)) + , m_argCount(argCount) + { + ASSERT(argCount >= 0); + } + + ArgList(const MarkedArgumentBuffer& args) + : m_args(reinterpret_cast(const_cast(args.begin()))) + , m_argCount(args.size()) + { + } + + JSValue at(size_t idx) const + { + if (idx < m_argCount) + return m_args[idx]; + return jsUndefined(); + } + + bool isEmpty() const { return !m_argCount; } + + size_t size() const { return m_argCount; } + + iterator begin() { return m_args; } + iterator end() { return m_args + m_argCount; } + + const_iterator begin() const { return m_args; } + const_iterator end() const { return m_args + m_argCount; } + + void getSlice(int startIndex, ArgList& result) const; + private: + JSValue* m_args; + size_t m_argCount; + }; + +} // namespace JSC + +#endif // ArgList_h