/*
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 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
#include "config.h"
#include "ArgList.h"
-#include "JSValue.h"
-#include "JSCell.h"
+#include "HeapRootVisitor.h"
+#include "JSCJSValue.h"
+#include "JSObject.h"
+#include "Operations.h"
using std::min;
void ArgList::getSlice(int startIndex, ArgList& result) const
{
- ASSERT(!result.m_isReadOnly);
+ if (startIndex <= 0 || startIndex >= m_argCount) {
+ result = ArgList();
+ return;
+ }
- const_iterator start = min(begin() + startIndex, end());
- result.m_vector.appendRange(start, end());
- result.m_size = result.m_vector.size();
- result.m_buffer = result.m_vector.data();
+ result.m_args = m_args - startIndex;
+ result.m_argCount = m_argCount - startIndex;
}
-void ArgList::markLists(ListSet& markSet)
+void MarkedArgumentBuffer::markLists(HeapRootVisitor& heapRootVisitor, ListSet& markSet)
{
ListSet::iterator end = markSet.end();
for (ListSet::iterator it = markSet.begin(); it != end; ++it) {
- ArgList* list = *it;
-
- iterator end2 = list->end();
- for (iterator it2 = list->begin(); it2 != end2; ++it2)
- if (!(*it2).marked())
- (*it2).mark();
+ MarkedArgumentBuffer* list = *it;
+ for (int i = 0; i < list->m_size; ++i)
+ heapRootVisitor.visit(reinterpret_cast<JSValue*>(&list->slotFor(i)));
}
}
-void ArgList::slowAppend(JSValuePtr v)
+void MarkedArgumentBuffer::slowAppend(JSValue v)
{
+ int newCapacity = m_capacity * 4;
+ EncodedJSValue* newBuffer = &(new EncodedJSValue[newCapacity])[newCapacity - 1];
+ for (int i = 0; i < m_capacity; ++i)
+ newBuffer[-i] = m_buffer[-i];
+
+ if (EncodedJSValue* base = mallocBase())
+ delete [] base;
+
+ m_buffer = newBuffer;
+ m_capacity = newCapacity;
+
+ slotFor(m_size) = JSValue::encode(v);
+ ++m_size;
+
+ if (m_markSet)
+ return;
+
// As long as our size stays within our Vector's inline
// capacity, all our values are allocated on the stack, and
// therefore don't need explicit marking. Once our size exceeds
// our Vector's inline capacity, though, our values move to the
// heap, where they do need explicit marking.
- if (!m_markSet) {
- // We can only register for explicit marking once we know which heap
- // is the current one, i.e., when a non-immediate value is appended.
- if (Heap* heap = Heap::heap(v)) {
- ListSet& markSet = heap->markListSet();
- markSet.add(this);
- m_markSet = &markSet;
- }
- }
+ for (int i = 0; i < m_size; ++i) {
+ Heap* heap = Heap::heap(JSValue::decode(slotFor(i)));
+ if (!heap)
+ continue;
- if (m_vector.size() < m_vector.capacity()) {
- m_vector.uncheckedAppend(v);
- return;
+ m_markSet = &heap->markListSet();
+ m_markSet->add(this);
+ break;
}
-
- // 4x growth would be excessive for a normal vector, but it's OK for Lists
- // because they're short-lived.
- m_vector.reserveCapacity(m_vector.capacity() * 4);
-
- m_vector.uncheckedAppend(v);
- m_buffer = m_vector.data();
}
} // namespace JSC