X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/ba379fdc102753d6be2c4d937058fe40257329fe..a253471d7f8e4d91bf6ebabab00155c3b387d3d0:/runtime/ArgList.h diff --git a/runtime/ArgList.h b/runtime/ArgList.h index 3c82561..1512a0f 100644 --- a/runtime/ArgList.h +++ b/runtime/ArgList.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008, 2009 Apple Computer, Inc. + * 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 @@ -22,138 +22,108 @@ #ifndef ArgList_h #define ArgList_h +#include "CallFrame.h" #include "Register.h" - +#include "WriteBarrier.h" #include -#include #include namespace JSC { - - class MarkedArgumentBuffer : Noncopyable { + + class SlotVisitor; + + class MarkedArgumentBuffer { + WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer); + friend class JSGlobalData; + friend class ArgList; + private: - static const unsigned inlineCapacity = 8; + static const size_t 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_size(0) + , m_capacity(inlineCapacity) + , m_buffer(&m_inlineBuffer[m_capacity - 1]) , 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); + + if (EncodedJSValue* base = mallocBase()) + delete [] base; } size_t size() const { return m_size; } bool isEmpty() const { return !m_size; } - JSValue at(size_t i) const + JSValue at(int i) const { - if (i < m_size) - return m_buffer[i].jsValue(); - return jsUndefined(); + if (i >= m_size) + return jsUndefined(); + + return JSValue::decode(slotFor(i)); } 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; - } + if (m_size >= m_capacity) + return slowAppend(v); + + slotFor(m_size) = JSValue::encode(v); + ++m_size; } void removeLast() { ASSERT(m_size); m_size--; - m_vector.removeLast(); } JSValue last() { ASSERT(m_size); - return m_buffer[m_size - 1].jsValue(); + return JSValue::decode(slotFor(m_size - 1)); } - 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(ListSet&); + static void markLists(HeapRootVisitor&, ListSet&); private: - void slowAppend(JSValue); + JS_EXPORT_PRIVATE void slowAppend(JSValue); - Register* m_buffer; - size_t m_size; - bool m_isUsingInlineBuffer; - - VectorType m_vector; + EncodedJSValue& slotFor(int item) const + { + return m_buffer[-item]; + } + + EncodedJSValue* mallocBase() + { + if (m_capacity == static_cast(inlineCapacity)) + return 0; + return &slotFor(m_capacity - 1); + } + + int m_size; + int m_capacity; + EncodedJSValue m_inlineBuffer[inlineCapacity]; + EncodedJSValue* m_buffer; 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); @@ -173,55 +143,39 @@ namespace JSC { 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) + + ArgList(ExecState* exec) + : m_args(reinterpret_cast(&exec[CallFrame::argumentOffset(0)])) + , m_argCount(exec->argumentCount()) { - ASSERT(argCount >= 0); } ArgList(const MarkedArgumentBuffer& args) - : m_args(reinterpret_cast(const_cast(args.begin()))) + : m_args(reinterpret_cast(args.m_buffer)) , m_argCount(args.size()) { } - JSValue at(size_t idx) const + JSValue at(int i) const { - if (idx < m_argCount) - return m_args[idx]; - return jsUndefined(); + if (i >= m_argCount) + return jsUndefined(); + return m_args[-i]; } 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; } + JS_EXPORT_PRIVATE void getSlice(int startIndex, ArgList& result) const; - void getSlice(int startIndex, ArgList& result) const; private: JSValue* m_args; - size_t m_argCount; + int m_argCount; }; } // namespace JSC