File: MarkingVisitorImpl.h

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (134 lines) | stat: -rw-r--r-- 4,278 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MarkingVisitorImpl_h
#define MarkingVisitorImpl_h

#include "platform/heap/Heap.h"
#include "platform/heap/ThreadState.h"
#include "platform/heap/Visitor.h"
#include "wtf/Functional.h"
#include "wtf/HashFunctions.h"
#include "wtf/Locker.h"
#include "wtf/RawPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/TypeTraits.h"

namespace blink {

template <typename Derived>
class MarkingVisitorImpl {
protected:
    inline void visitHeader(HeapObjectHeader* header, const void* objectPointer, TraceCallback callback)
    {
        ASSERT(header);
        ASSERT(objectPointer);
        // Check that we are not marking objects that are outside
        // the heap by calling Heap::contains.  However we cannot
        // call Heap::contains when outside a GC and we call mark
        // when doing weakness for ephemerons.  Hence we only check
        // when called within.
        ASSERT(!ThreadState::current()->isInGC() || Heap::containedInHeapOrOrphanedPage(header));

        if (!toDerived()->shouldMarkObject(objectPointer))
            return;

        // If you hit this ASSERT, it means that there is a dangling pointer
        // from a live thread heap to a dead thread heap.  We must eliminate
        // the dangling pointer.
        // Release builds don't have the ASSERT, but it is OK because
        // release builds will crash in the following header->isMarked()
        // because all the entries of the orphaned heaps are zapped.
        ASSERT(!pageFromObject(objectPointer)->orphaned());

        if (header->isMarked())
            return;
        header->mark();

#if ENABLE(GC_PROFILE_MARKING)
        toDerived()->recordObjectGraphEdge(objectPointer);
#endif

        if (callback)
            Heap::pushTraceCallback(const_cast<void*>(objectPointer), callback);
    }

    inline void mark(const void* objectPointer, TraceCallback callback)
    {
        if (!objectPointer)
            return;
        HeapObjectHeader* header = HeapObjectHeader::fromPayload(objectPointer);
        visitHeader(header, header->payload(), callback);
    }

    inline void registerDelayedMarkNoTracing(const void* objectPointer)
    {
        Heap::pushPostMarkingCallback(const_cast<void*>(objectPointer), &markNoTracingCallback);
    }

    inline void registerWeakMembers(const void* closure, const void* objectPointer, WeakPointerCallback callback)
    {
        Heap::pushWeakPointerCallback(const_cast<void*>(closure), const_cast<void*>(objectPointer), callback);
    }

    inline void registerWeakTable(const void* closure, EphemeronCallback iterationCallback, EphemeronCallback iterationDoneCallback)
    {
        Heap::registerWeakTable(const_cast<void*>(closure), iterationCallback, iterationDoneCallback);
    }

#if ENABLE(ASSERT)
    inline bool weakTableRegistered(const void* closure)
    {
        return Heap::weakTableRegistered(closure);
    }
#endif

    inline bool isMarked(const void* objectPointer)
    {
        return HeapObjectHeader::fromPayload(objectPointer)->isMarked();
    }

    inline bool ensureMarked(const void* objectPointer)
    {
        if (!objectPointer)
            return false;
        if (!toDerived()->shouldMarkObject(objectPointer))
            return false;
#if ENABLE(ASSERT)
        if (isMarked(objectPointer))
            return false;

        toDerived()->markNoTracing(objectPointer);
#else
        // Inline what the above markNoTracing() call expands to,
        // so as to make sure that we do get all the benefits.
        HeapObjectHeader* header = HeapObjectHeader::fromPayload(objectPointer);
        if (header->isMarked())
            return false;
        header->mark();
#endif
        return true;
    }

    Derived* toDerived()
    {
        return static_cast<Derived*>(this);
    }

protected:
    inline void registerWeakCellWithCallback(void** cell, WeakPointerCallback callback)
    {
        Heap::pushWeakCellPointerCallback(cell, callback);
    }

private:
    static void markNoTracingCallback(Visitor* visitor, void* object)
    {
        visitor->markNoTracing(object);
    }
};

} // namespace blink

#endif