summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/collector/handles/HandleHeap.h
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-24 11:24:40 +0100
committerBen Murdoch <benm@google.com>2011-06-02 09:53:15 +0100
commit81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch)
tree7a9e5ed86ff429fd347a25153107221543909b19 /Source/JavaScriptCore/collector/handles/HandleHeap.h
parent94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff)
downloadexternal_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/JavaScriptCore/collector/handles/HandleHeap.h')
-rw-r--r--Source/JavaScriptCore/collector/handles/HandleHeap.h273
1 files changed, 273 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/collector/handles/HandleHeap.h b/Source/JavaScriptCore/collector/handles/HandleHeap.h
new file mode 100644
index 0000000..4bb9b00
--- /dev/null
+++ b/Source/JavaScriptCore/collector/handles/HandleHeap.h
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 HandleHeap_h
+#define HandleHeap_h
+
+#include "BlockStack.h"
+#include "Handle.h"
+#include "SentinelLinkedList.h"
+#include "SinglyLinkedList.h"
+
+namespace JSC {
+
+class HandleHeap;
+class JSGlobalData;
+class JSValue;
+class MarkStack;
+
+class Finalizer {
+public:
+ virtual void finalize(Handle<Unknown>, void*) = 0;
+ virtual ~Finalizer() {}
+};
+
+class HandleHeap {
+public:
+ static HandleHeap* heapFor(HandleSlot);
+
+ HandleHeap(JSGlobalData*);
+
+ HandleSlot allocate();
+ void deallocate(HandleSlot);
+
+ void makeWeak(HandleSlot, Finalizer*, void* context);
+ void makeSelfDestroying(HandleSlot, Finalizer*, void* context);
+
+ void markStrongHandles(MarkStack&);
+ void updateAfterMark();
+
+ // Should only be called during teardown.
+ void clearWeakPointers();
+
+ void writeBarrier(HandleSlot, const JSValue&);
+
+#if !ASSERT_DISABLED
+ Finalizer* getFinalizer(HandleSlot handle)
+ {
+ return toNode(handle)->finalizer();
+ }
+#endif
+
+ unsigned protectedGlobalObjectCount();
+
+private:
+ typedef uintptr_t HandleHeapWithFlags;
+ enum { FlagsMask = 3, WeakFlag = 1, SelfDestroyingFlag = 2 };
+ class Node {
+ public:
+ Node(WTF::SentinelTag);
+ Node(HandleHeap*);
+
+ HandleSlot slot();
+ HandleHeap* handleHeap();
+
+ void setFinalizer(Finalizer*, void* context);
+ Finalizer* finalizer();
+ void* finalizerContext();
+
+ void setPrev(Node*);
+ Node* prev();
+
+ void setNext(Node*);
+ Node* next();
+
+ bool isWeak();
+ void makeWeak();
+
+ bool isSelfDestroying();
+ void makeSelfDestroying();
+
+ private:
+ JSValue m_value;
+ HandleHeapWithFlags m_handleHeapWithFlags;
+ Finalizer* m_finalizer;
+ void* m_finalizerContext;
+ Node* m_prev;
+ Node* m_next;
+ };
+
+ static HandleSlot toHandle(Node*);
+ static Node* toNode(HandleSlot);
+
+ void grow();
+
+ JSGlobalData* m_globalData;
+ BlockStack<Node> m_blockStack;
+
+ SentinelLinkedList<Node> m_strongList;
+ SentinelLinkedList<Node> m_weakList;
+ SentinelLinkedList<Node> m_immediateList;
+ SinglyLinkedList<Node> m_freeList;
+ Node* m_nextToFinalize;
+
+#if !ASSERT_DISABLED
+ bool m_handlingFinalizers;
+#endif
+};
+
+inline HandleHeap* HandleHeap::heapFor(HandleSlot handle)
+{
+ return toNode(handle)->handleHeap();
+}
+
+inline HandleSlot HandleHeap::toHandle(Node* node)
+{
+ return reinterpret_cast<HandleSlot>(node);
+}
+
+inline HandleHeap::Node* HandleHeap::toNode(HandleSlot handle)
+{
+ return reinterpret_cast<Node*>(handle);
+}
+
+inline HandleSlot HandleHeap::allocate()
+{
+ if (m_freeList.isEmpty())
+ grow();
+
+ Node* node = m_freeList.pop();
+ new (node) Node(this);
+ m_immediateList.push(node);
+ return toHandle(node);
+}
+
+inline void HandleHeap::deallocate(HandleSlot handle)
+{
+ Node* node = toNode(handle);
+ if (m_nextToFinalize == node) {
+ m_nextToFinalize = node->next();
+ ASSERT(m_nextToFinalize->next());
+ }
+ SentinelLinkedList<Node>::remove(node);
+ m_freeList.push(node);
+}
+
+inline void HandleHeap::makeWeak(HandleSlot handle, Finalizer* finalizer, void* context)
+{
+ Node* node = toNode(handle);
+ SentinelLinkedList<Node>::remove(node);
+ node->setFinalizer(finalizer, context);
+ node->makeWeak();
+ if (handle->isCell() && *handle)
+ m_weakList.push(node);
+ else
+ m_immediateList.push(node);
+}
+
+inline void HandleHeap::makeSelfDestroying(HandleSlot handle, Finalizer* finalizer, void* context)
+{
+ makeWeak(handle, finalizer, context);
+ Node* node = toNode(handle);
+ node->makeSelfDestroying();
+}
+
+inline HandleHeap::Node::Node(HandleHeap* handleHeap)
+ : m_handleHeapWithFlags(reinterpret_cast<uintptr_t>(handleHeap))
+ , m_finalizer(0)
+ , m_finalizerContext(0)
+{
+}
+
+inline HandleHeap::Node::Node(WTF::SentinelTag)
+ : m_handleHeapWithFlags(0)
+ , m_finalizer(0)
+ , m_finalizerContext(0)
+{
+}
+
+inline HandleSlot HandleHeap::Node::slot()
+{
+ return &m_value;
+}
+
+inline HandleHeap* HandleHeap::Node::handleHeap()
+{
+ return reinterpret_cast<HandleHeap*>(m_handleHeapWithFlags & ~FlagsMask);
+}
+
+inline void HandleHeap::Node::setFinalizer(Finalizer* finalizer, void* context)
+{
+ m_finalizer = finalizer;
+ m_finalizerContext = context;
+}
+
+inline void HandleHeap::Node::makeWeak()
+{
+ ASSERT(!(m_handleHeapWithFlags & WeakFlag));
+ m_handleHeapWithFlags |= WeakFlag;
+}
+
+inline bool HandleHeap::Node::isWeak()
+{
+ return !!(m_handleHeapWithFlags & WeakFlag);
+}
+
+inline void HandleHeap::Node::makeSelfDestroying()
+{
+ ASSERT(m_handleHeapWithFlags & WeakFlag);
+ ASSERT(!(m_handleHeapWithFlags & SelfDestroyingFlag));
+ m_handleHeapWithFlags |= SelfDestroyingFlag;
+}
+
+inline bool HandleHeap::Node::isSelfDestroying()
+{
+ return !!(m_handleHeapWithFlags & SelfDestroyingFlag);
+}
+
+inline Finalizer* HandleHeap::Node::finalizer()
+{
+ return m_finalizer;
+}
+
+inline void* HandleHeap::Node::finalizerContext()
+{
+ ASSERT(m_finalizer);
+ return m_finalizerContext;
+}
+
+inline void HandleHeap::Node::setPrev(Node* prev)
+{
+ m_prev = prev;
+}
+
+inline HandleHeap::Node* HandleHeap::Node::prev()
+{
+ return m_prev;
+}
+
+inline void HandleHeap::Node::setNext(Node* next)
+{
+ m_next = next;
+}
+
+inline HandleHeap::Node* HandleHeap::Node::next()
+{
+ return m_next;
+}
+
+}
+
+#endif