summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/runtime/MarkStack.h
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2009-08-11 17:01:47 +0100
committerBen Murdoch <benm@google.com>2009-08-11 18:21:02 +0100
commit0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5 (patch)
tree2943df35f62d885c89d01063cc528dd73b480fea /JavaScriptCore/runtime/MarkStack.h
parent7e7a70bfa49a1122b2597a1e6367d89eb4035eca (diff)
downloadexternal_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.zip
external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.gz
external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.bz2
Merge in WebKit r47029.
Diffstat (limited to 'JavaScriptCore/runtime/MarkStack.h')
-rw-r--r--JavaScriptCore/runtime/MarkStack.h171
1 files changed, 171 insertions, 0 deletions
diff --git a/JavaScriptCore/runtime/MarkStack.h b/JavaScriptCore/runtime/MarkStack.h
new file mode 100644
index 0000000..7a7b3af
--- /dev/null
+++ b/JavaScriptCore/runtime/MarkStack.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MarkStack_h
+#define MarkStack_h
+
+#include "JSValue.h"
+
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+ class Register;
+
+ enum MarkSetProperties { MayContainNullValues, NoNullValues };
+
+ class MarkStack : Noncopyable {
+ public:
+ MarkStack()
+ : m_markSets()
+ , m_values()
+ {
+ }
+
+ ALWAYS_INLINE void append(JSValue value)
+ {
+ ASSERT(value);
+ if (value.marked())
+ return;
+ value.markDirect();
+ if (value.hasChildren())
+ m_values.append(value.asCell());
+ }
+
+ ALWAYS_INLINE void append(JSCell* cell);
+
+ ALWAYS_INLINE void appendValues(Register* values, size_t count, MarkSetProperties properties = NoNullValues)
+ {
+ appendValues(reinterpret_cast<JSValue*>(values), count, properties);
+ }
+
+ ALWAYS_INLINE void appendValues(JSValue* values, size_t count, MarkSetProperties properties = NoNullValues)
+ {
+ if (count)
+ m_markSets.append(MarkSet(values, values + count, properties));
+ }
+
+ inline void drain();
+ void compact();
+
+ ~MarkStack()
+ {
+ ASSERT(m_markSets.isEmpty());
+ ASSERT(m_values.isEmpty());
+ }
+
+ private:
+ struct MarkSet {
+ MarkSet(JSValue* values, JSValue* end, MarkSetProperties properties)
+ : m_values(values)
+ , m_end(end)
+ , m_properties(properties)
+ {
+ }
+ JSValue* m_values;
+ JSValue* m_end;
+ MarkSetProperties m_properties;
+ };
+
+ static void* allocateStack(size_t size);
+ static void releaseStack(void* addr, size_t size);
+
+ static void initializePagesize();
+ static size_t pageSize()
+ {
+ if (!s_pageSize)
+ initializePagesize();
+ return s_pageSize;
+ }
+
+ template <typename T> struct MarkStackArray {
+ MarkStackArray()
+ : m_top(0)
+ , m_allocated(MarkStack::pageSize())
+ , m_capacity(m_allocated / sizeof(T))
+ {
+ m_data = reinterpret_cast<T*>(allocateStack(m_allocated));
+ }
+
+ ~MarkStackArray()
+ {
+ releaseStack(m_data, m_allocated);
+ }
+
+ void expand()
+ {
+ size_t oldAllocation = m_allocated;
+ m_allocated *= 2;
+ m_capacity = m_allocated / sizeof(T);
+ void* newData = allocateStack(m_allocated);
+ memcpy(newData, m_data, oldAllocation);
+ releaseStack(m_data, oldAllocation);
+ m_data = reinterpret_cast<T*>(newData);
+ }
+
+ inline void append(const T& v)
+ {
+ if (m_top == m_capacity)
+ expand();
+ m_data[m_top++] = v;
+ }
+
+ inline T removeLast()
+ {
+ ASSERT(m_top);
+ return m_data[--m_top];
+ }
+
+ inline bool isEmpty()
+ {
+ return m_top == 0;
+ }
+
+ inline size_t size() { return m_top; }
+
+ inline void shrinkAllocation(size_t size)
+ {
+ ASSERT(size <= m_allocated);
+ ASSERT(0 == (size % MarkStack::pageSize()));
+ if (size == m_allocated)
+ return;
+ releaseStack(reinterpret_cast<char*>(m_data) + size, m_allocated - size);
+ m_allocated = size;
+ m_capacity = m_allocated / sizeof(T);
+ }
+
+ private:
+ size_t m_top;
+ size_t m_allocated;
+ size_t m_capacity;
+ T* m_data;
+ };
+
+ MarkStackArray<MarkSet> m_markSets;
+ MarkStackArray<JSCell*> m_values;
+ static size_t s_pageSize;
+ };
+}
+
+#endif