181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch/*
281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Copyright (C) 2011 Apple Inc. All rights reserved.
381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *
481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Redistribution and use in source and binary forms, with or without
581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * modification, are permitted provided that the following conditions
681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * are met:
781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * 1. Redistributions of source code must retain the above copyright
881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *    notice, this list of conditions and the following disclaimer.
981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright
1081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *    notice, this list of conditions and the following disclaimer in the
1181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *    documentation and/or other materials provided with the distribution.
1281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *
1381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
1481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
1781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * THE POSSIBILITY OF SUCH DAMAGE.
2481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch */
2581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#ifndef HandleHeap_h
2781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#define HandleHeap_h
2881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "BlockStack.h"
3081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "Handle.h"
3181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "SentinelLinkedList.h"
3281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "SinglyLinkedList.h"
3381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
3481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochnamespace JSC {
3581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
3681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochclass HandleHeap;
372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass HeapRootMarker;
3881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochclass JSGlobalData;
3981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochclass JSValue;
402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass MarkStack;
412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass TypeCounter;
4281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass WeakHandleOwner {
4481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochpublic:
452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    virtual ~WeakHandleOwner();
462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    virtual bool isReachableFromOpaqueRoots(Handle<Unknown>, void* context, MarkStack&);
472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    virtual void finalize(Handle<Unknown>, void* context);
4881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch};
4981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochclass HandleHeap {
5181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochpublic:
5281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    static HandleHeap* heapFor(HandleSlot);
5381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    HandleHeap(JSGlobalData*);
552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    JSGlobalData* globalData();
5781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    HandleSlot allocate();
5981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    void deallocate(HandleSlot);
602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    void makeWeak(HandleSlot, WeakHandleOwner* = 0, void* context = 0);
622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    HandleSlot copyWeak(HandleSlot);
6381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
642bde8e466a4451c7319e3a072d118917957d6554Steve Block    void markStrongHandles(HeapRootMarker&);
652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    void markWeakHandles(HeapRootMarker&);
662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    void finalizeWeakHandles();
6781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
6881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    void writeBarrier(HandleSlot, const JSValue&);
6981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
7081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if !ASSERT_DISABLED
712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    bool hasWeakOwner(HandleSlot, WeakHandleOwner*);
7281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif
7381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
7481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    unsigned protectedGlobalObjectCount();
752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    void protectedObjectTypeCounts(TypeCounter&);
762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
7781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochprivate:
7881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    class Node {
7981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    public:
8081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        Node(WTF::SentinelTag);
8181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        Node(HandleHeap*);
8281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
8381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        HandleSlot slot();
8481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        HandleHeap* handleHeap();
8581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        void makeWeak(WeakHandleOwner*, void* context);
872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        bool isWeak();
882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        WeakHandleOwner* weakOwner();
902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        void* weakOwnerContext();
9181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
9281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        void setPrev(Node*);
9381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        Node* prev();
9481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
9581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        void setNext(Node*);
9681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        Node* next();
9781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
9881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    private:
992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        WeakHandleOwner* emptyWeakOwner();
1002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
10181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        JSValue m_value;
1022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        HandleHeap* m_handleHeap;
1032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        WeakHandleOwner* m_weakOwner;
1042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        void* m_weakOwnerContext;
10581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        Node* m_prev;
10681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        Node* m_next;
10781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    };
10881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
10981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    static HandleSlot toHandle(Node*);
11081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    static Node* toNode(HandleSlot);
11181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
11281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    void grow();
1132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if !ASSERT_DISABLED
1152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    bool isValidWeakNode(Node*);
1162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif
11781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
11881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    JSGlobalData* m_globalData;
11981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    BlockStack<Node> m_blockStack;
12081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
12181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    SentinelLinkedList<Node> m_strongList;
12281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    SentinelLinkedList<Node> m_weakList;
12381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    SentinelLinkedList<Node> m_immediateList;
12481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    SinglyLinkedList<Node> m_freeList;
12581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Node* m_nextToFinalize;
12681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch};
12781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
12881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline HandleHeap* HandleHeap::heapFor(HandleSlot handle)
12981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
13081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return toNode(handle)->handleHeap();
13181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
13281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochinline JSGlobalData* HandleHeap::globalData()
1342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return m_globalData;
1362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
13881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline HandleSlot HandleHeap::toHandle(Node* node)
13981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
14081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return reinterpret_cast<HandleSlot>(node);
14181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
14281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
14381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline HandleHeap::Node* HandleHeap::toNode(HandleSlot handle)
14481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
14581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return reinterpret_cast<Node*>(handle);
14681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
14781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
14881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline HandleSlot HandleHeap::allocate()
14981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
15081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_freeList.isEmpty())
15181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        grow();
15281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
15381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Node* node = m_freeList.pop();
15481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    new (node) Node(this);
15581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_immediateList.push(node);
15681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return toHandle(node);
15781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
15881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
15981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void HandleHeap::deallocate(HandleSlot handle)
16081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
16181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Node* node = toNode(handle);
1622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (node == m_nextToFinalize) {
16381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_nextToFinalize = node->next();
16481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT(m_nextToFinalize->next());
16581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
1662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
16781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    SentinelLinkedList<Node>::remove(node);
16881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_freeList.push(node);
16981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
17081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochinline HandleSlot HandleHeap::copyWeak(HandleSlot other)
1722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    Node* node = toNode(allocate());
1742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    node->makeWeak(toNode(other)->weakOwner(), toNode(other)->weakOwnerContext());
1752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    writeBarrier(node->slot(), *other);
1762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    *node->slot() = *other;
1772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return toHandle(node);
1782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochinline void HandleHeap::makeWeak(HandleSlot handle, WeakHandleOwner* weakOwner, void* context)
18181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
18281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Node* node = toNode(handle);
1832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    node->makeWeak(weakOwner, context);
1842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
18581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    SentinelLinkedList<Node>::remove(node);
1862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!*handle || !handle->isCell()) {
18781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_immediateList.push(node);
1882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return;
1892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
1902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    m_weakList.push(node);
19281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
19381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if !ASSERT_DISABLED
1952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochinline bool HandleHeap::hasWeakOwner(HandleSlot handle, WeakHandleOwner* weakOwner)
19681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
1972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return toNode(handle)->weakOwner() == weakOwner;
19881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
1992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif
20081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
20181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline HandleHeap::Node::Node(HandleHeap* handleHeap)
2022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    : m_handleHeap(handleHeap)
2032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    , m_weakOwner(0)
2042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    , m_weakOwnerContext(0)
20581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
20681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
20781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
20881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline HandleHeap::Node::Node(WTF::SentinelTag)
2092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    : m_handleHeap(0)
2102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    , m_weakOwner(0)
2112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    , m_weakOwnerContext(0)
21281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
21381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
21481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
21581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline HandleSlot HandleHeap::Node::slot()
21681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
21781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return &m_value;
21881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
21981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
22081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline HandleHeap* HandleHeap::Node::handleHeap()
22181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
2222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return m_handleHeap;
22381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
22481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochinline void HandleHeap::Node::makeWeak(WeakHandleOwner* weakOwner, void* context)
22681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
2272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    m_weakOwner = weakOwner ? weakOwner : emptyWeakOwner();
2282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    m_weakOwnerContext = context;
22981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
23081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
23181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline bool HandleHeap::Node::isWeak()
23281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
2332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return m_weakOwner; // True for emptyWeakOwner().
23481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
23581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochinline WeakHandleOwner* HandleHeap::Node::weakOwner()
23781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
2382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return m_weakOwner == emptyWeakOwner() ? 0 : m_weakOwner; // 0 for emptyWeakOwner().
23981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
24081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochinline void* HandleHeap::Node::weakOwnerContext()
24281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
2432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(weakOwner());
2442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return m_weakOwnerContext;
24581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
24681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
24781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void HandleHeap::Node::setPrev(Node* prev)
24881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
24981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_prev = prev;
25081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
25181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
25281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline HandleHeap::Node* HandleHeap::Node::prev()
25381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
25481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return m_prev;
25581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
25681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
25781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline void HandleHeap::Node::setNext(Node* next)
25881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
25981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_next = next;
26081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
26181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
26281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochinline HandleHeap::Node* HandleHeap::Node::next()
26381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
26481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return m_next;
26581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
26681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Sentinel to indicate that a node is weak, but its owner has no meaningful
2682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// callbacks. This allows us to optimize by skipping such nodes.
2692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochinline WeakHandleOwner* HandleHeap::Node::emptyWeakOwner()
2702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
2712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return reinterpret_cast<WeakHandleOwner*>(-1);
2722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
2732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
27481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
27581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
27681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif
277