summaryrefslogtreecommitdiffstats
path: root/js/src/gc/Marking.h
blob: ed146ee236398d2b079d3dc7e25bd3b6f1ff074c (plain)
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * Marking and sweeping APIs for use by implementations of different GC cell
 * kinds.
 */

#ifndef gc_Marking_h
#define gc_Marking_h

#include "gc/Barrier.h"
#include "gc/Tracer.h"
#include "js/TypeDecls.h"

class JSTracer;
struct JSClass;

namespace js {
class GCMarker;
class Shape;
class WeakMapBase;

namespace gc {

struct Cell;

/*** Liveness ***/

// The IsMarkedInternal and IsAboutToBeFinalizedInternal function templates are
// used to implement the IsMarked and IsAboutToBeFinalized set of functions.
// These internal functions are instantiated for the base GC types and should
// not be called directly.
//
// Note that there are two function templates declared for each, not one
// template and a specialization. This is necessary so that pointer arguments
// (e.g. JSObject**) and tagged value arguments (e.g. JS::Value*) are routed to
// separate implementations.

template <typename T>
bool IsMarkedInternal(JSRuntime* rt, T* thing);

template <typename T>
bool IsAboutToBeFinalizedInternal(T* thing);
template <typename T>
bool IsAboutToBeFinalizedInternal(const T& thing);

// Report whether a GC thing has been marked with any color. Things which are in
// zones that are not currently being collected or are owned by another runtime
// are always reported as being marked.
template <typename T>
inline bool IsMarked(JSRuntime* rt, const BarrieredBase<T>& thing) {
  return IsMarkedInternal(rt, *ConvertToBase(thing.unbarrieredAddress()));
}
template <typename T>
inline bool IsMarkedUnbarriered(JSRuntime* rt, T thing) {
  return IsMarkedInternal(rt, *ConvertToBase(&thing));
}

// Report whether a GC thing is dead and will be finalized in the current sweep
// group. This is mainly used in read barriers for incremental sweeping.
//
// This no longer updates pointers moved by the GC (tracing should be used for
// this instead).
template <typename T>
inline bool IsAboutToBeFinalized(const BarrieredBase<T>& thing) {
  return IsAboutToBeFinalizedInternal(
      *ConvertToBase(thing.unbarrieredAddress()));
}
template <typename T>
inline bool IsAboutToBeFinalizedUnbarriered(T* thing) {
  return IsAboutToBeFinalizedInternal(*ConvertToBase(&thing));
}
template <typename T>
inline bool IsAboutToBeFinalizedUnbarriered(const T& thing) {
  return IsAboutToBeFinalizedInternal(thing);
}

inline bool IsAboutToBeFinalizedDuringMinorSweep(Cell* cell);

inline Cell* ToMarkable(const Value& v) {
  if (v.isGCThing()) {
    return (Cell*)v.toGCThing();
  }
  return nullptr;
}

inline Cell* ToMarkable(Cell* cell) { return cell; }

bool UnmarkGrayGCThingUnchecked(GCMarker* marker, JS::GCCellPtr thing);

} /* namespace gc */

// The return value indicates if anything was unmarked.
bool UnmarkGrayShapeRecursively(Shape* shape);

namespace gc {

// Functions for checking and updating GC thing pointers that might have been
// moved by compacting GC. Overloads are also provided that work with Values.
//
// IsForwarded    - check whether a pointer refers to an GC thing that has been
//                  moved.
//
// Forwarded      - return a pointer to the new location of a GC thing given a
//                  pointer to old location.
//
// MaybeForwarded - used before dereferencing a pointer that may refer to a
//                  moved GC thing without updating it. For JSObjects this will
//                  also update the object's shape pointer if it has been moved
//                  to allow slots to be accessed.

template <typename T>
inline bool IsForwarded(const T* t);

template <typename T>
inline T* Forwarded(const T* t);

inline Value Forwarded(const JS::Value& value);

template <typename T>
inline T MaybeForwarded(T t);

// Helper functions for use in situations where the object's group might be
// forwarded, for example while marking.

inline const JSClass* MaybeForwardedObjectClass(const JSObject* obj);

template <typename T>
inline bool MaybeForwardedObjectIs(const JSObject* obj);

template <typename T>
inline T& MaybeForwardedObjectAs(JSObject* obj);

#ifdef JSGC_HASH_TABLE_CHECKS

template <typename T>
inline bool IsGCThingValidAfterMovingGC(T* t);

template <typename T>
inline void CheckGCThingAfterMovingGC(T* t);

template <typename T>
inline void CheckGCThingAfterMovingGC(const WeakHeapPtr<T*>& t);

#endif  // JSGC_HASH_TABLE_CHECKS

} /* namespace gc */

} /* namespace js */

#endif /* gc_Marking_h */