DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (a4e764f8dda4)

VCS Links

Line Code
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 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
/* -*- 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 "js/TypeDecls.h"
#include "vm/TaggedProto.h"

class JSLinearString;
class JSRope;
class JSTracer;

namespace js {
class BaseShape;
class GCMarker;
class LazyScript;
class NativeObject;
class ObjectGroup;
class Shape;
class WeakMapBase;

namespace jit {
class JitCode;
}  // namespace jit

#ifdef DEBUG
// Return true if this trace is happening on behalf of gray buffering during
// the marking phase of incremental GC.
bool IsBufferGrayRootsTracer(JSTracer* trc);

bool IsUnmarkGrayTracer(JSTracer* trc);
#endif

namespace gc {

class Arena;
struct Cell;
class TenuredCell;

/*** Special Cases ***/

void PushArena(GCMarker* gcmarker, Arena* arena);

/*** 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 IsMarkedInternal(JSRuntime* rt, T** thing);

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

template <typename T>
bool IsAboutToBeFinalizedInternal(T* thingp);
template <typename T>
bool IsAboutToBeFinalizedInternal(T** thingp);

// 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 IsMarkedUnbarriered(JSRuntime* rt, T* thingp) {
  return IsMarkedInternal(rt, ConvertToBase(thingp));
}

// 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, WriteBarriered<T>* thingp) {
  return IsMarkedInternal(rt,
                          ConvertToBase(thingp->unsafeUnbarrieredForTracing()));
}

// Report whether a GC thing has been marked black.
template <typename T>
inline bool IsMarkedBlackUnbarriered(JSRuntime* rt, T* thingp) {
  return IsMarkedBlackInternal(rt, ConvertToBase(thingp));
}

// Report whether a GC thing has been marked black.
template <typename T>
inline bool IsMarkedBlack(JSRuntime* rt, WriteBarriered<T>* thingp) {
  return IsMarkedBlackInternal(
      rt, ConvertToBase(thingp->unsafeUnbarrieredForTracing()));
}

template <typename T>
inline bool IsAboutToBeFinalizedUnbarriered(T* thingp) {
  return IsAboutToBeFinalizedInternal(ConvertToBase(thingp));
}

template <typename T>
inline bool IsAboutToBeFinalized(WriteBarriered<T>* thingp) {
  return IsAboutToBeFinalizedInternal(
      ConvertToBase(thingp->unsafeUnbarrieredForTracing()));
}

template <typename T>
inline bool IsAboutToBeFinalized(ReadBarriered<T>* thingp) {
  return IsAboutToBeFinalizedInternal(
      ConvertToBase(thingp->unsafeUnbarrieredForTracing()));
}

bool IsAboutToBeFinalizedDuringSweep(TenuredCell& tenured);

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

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

} /* namespace gc */

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

template <typename T>
void CheckTracedThing(JSTracer* trc, T* thing);

template <typename T>
void CheckTracedThing(JSTracer* trc, T thing);

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);
inline bool IsForwarded(const JS::Value& value);

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

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

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

#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);

inline void CheckValueAfterMovingGC(const JS::Value& value);

#endif  // JSGC_HASH_TABLE_CHECKS

} /* namespace gc */
} /* namespace js */

#endif /* gc_Marking_h */