Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/js/src/gc/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 7 kB image not shown  

Quelle  Heap-inl.h

  Sprache: C
 

/* 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/. */


#ifndef gc_Heap_inl_h
#define gc_Heap_inl_h

#include "gc/Heap.h"

#include "gc/StoreBuffer.h"
#include "gc/Zone.h"
#include "util/Poison.h"
#include "vm/Runtime.h"

inline void js::gc::Arena::init(GCRuntime* gc, AllocKind kind) {
  MOZ_ASSERT(IsValidAllocKind(kind));

  MOZ_MAKE_MEM_UNDEFINED(this, ArenaSize);

  allocKind = kind;
  next = nullptr;
  isNewlyCreated_ = 1;
  onDelayedMarkingList_ = 0;
  hasDelayedBlackMarking_ = 0;
  hasDelayedGrayMarking_ = 0;
  nextDelayedMarkingArena_ = 0;
  if (zone()->isAtomsZone()) {
    atomBitmapStart() = gc->atomMarking.allocateIndex(gc);
  } else {
    bufferedCells() = &ArenaCellSet::Empty;
  }

  setAsFullyUnused();  // Initializes firstFreeSpan.

#ifdef DEBUG
  checkNoMarkedCells();
#endif
}

inline JS::Zone* js::gc::Arena::zone() const { return chunk()->info.zone; }

inline void js::gc::Arena::freeAtomMarkingBitmapIndex(GCRuntime* gc,
                                                      const AutoLockGC& lock) {
  MOZ_ASSERT(zone()->isAtomsZone());
  gc->atomMarking.freeIndex(atomBitmapStart(), lock);
#ifdef DEBUG
  atomBitmapStart() = 0;  // Also zeroed by write to bufferedCells_ in release.
#endif
}

inline void js::gc::Arena::release() {
  MOZ_ASSERT(allocated());

  // Clients should call freeAtomMarkingBitmapIndex() if necessary.
  MOZ_ASSERT_IF(zone()->isAtomsZone(), atomBitmapStart_ == 0);

  firstFreeSpan.initAsEmpty();
  allocKind = AllocKind::LIMIT;
  onDelayedMarkingList_ = 0;
  hasDelayedBlackMarking_ = 0;
  hasDelayedGrayMarking_ = 0;
  nextDelayedMarkingArena_ = 0;
  bufferedCells_ = nullptr;

  MOZ_ASSERT(!allocated());
}

inline js::gc::ArenaCellSet*& js::gc::Arena::bufferedCells() {
  MOZ_ASSERT(!zone()->isAtomsZone());
  return bufferedCells_;
}

inline size_t& js::gc::Arena::atomBitmapStart() {
  MOZ_ASSERT(zone()->isAtomsZone());
  return atomBitmapStart_;
}

// Mark bitmap API:

// Unless noted otherwise, the following methods that update the mark bits are
// not thread safe and must not be called in parallel with each other.
//
// They use separate read and write operations to avoid an unnecessarily strict
// atomic update on the marking bitmap.
//
// They may be called in parallel with read operations on the mark bitmap where
// there is no required ordering between the operations. This happens when gray
// unmarking occurs in parallel with background sweeping.

// The return value indicates if the cell went from unmarked to marked.
MOZ_ALWAYS_INLINE bool js::gc::ChunkMarkBitmap::markIfUnmarked(
    const void* cell, MarkColor color) {
  Word* word;
  uintptr_t mask;
  getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask);
  if (*word & mask) {
    return false;
  }
  if (color == MarkColor::Black) {
    uintptr_t bits = *word;
    *word = bits | mask;
  } else {
    // We use getMarkWordAndMask to recalculate both mask and word as doing just
    // mask << color may overflow the mask.
    getMarkWordAndMask(cell, ColorBit::GrayOrBlackBit, &word, &mask);
    if (*word & mask) {
      return false;
    }
    uintptr_t bits = *word;
    *word = bits | mask;
  }
  return true;
}

// This version of the method is safe in the face of concurrent writes to the
// mark bitmap but if two threads attempt to mark the same cell at the same time
// then both calls can succeed and return true.
//
// This method is used for parallel marking where the extra synchronization
// required to avoid this results in worse performance overall.
MOZ_ALWAYS_INLINE bool js::gc::ChunkMarkBitmap::markIfUnmarkedThreadSafe(
    const void* cell, MarkColor color) {
  Word* word;
  uintptr_t mask;
  getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask);
  if (*word & mask) {
    return false;
  }
  if (color == MarkColor::Black) {
    *word |= mask;
  } else {
    // We use getMarkWordAndMask to recalculate both mask and word as doing just
    // mask << color may overflow the mask.
    getMarkWordAndMask(cell, ColorBit::GrayOrBlackBit, &word, &mask);
    if (*word & mask) {
      return false;
    }
    *word |= mask;
  }
  return true;
}

MOZ_ALWAYS_INLINE void js::gc::ChunkMarkBitmap::markBlack(const void* cell) {
  Word* word;
  uintptr_t mask;
  getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask);
  uintptr_t bits = *word;
  *word = bits | mask;
}

MOZ_ALWAYS_INLINE void js::gc::ChunkMarkBitmap::markBlackAtomic(
    const void* cell) {
  Word* word;
  uintptr_t mask;
  getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask);
  *word |= mask;
}

MOZ_ALWAYS_INLINE void js::gc::ChunkMarkBitmap::copyMarkBit(
    TenuredCell* dst, const TenuredCell* src, ColorBit colorBit) {
  ArenaChunkBase* srcChunk = detail::GetCellChunkBase(src);
  Word* srcWord;
  uintptr_t srcMask;
  srcChunk->markBits.getMarkWordAndMask(src, colorBit, &srcWord, &srcMask);

  Word* dstWord;
  uintptr_t dstMask;
  getMarkWordAndMask(dst, colorBit, &dstWord, &dstMask);

  uintptr_t bits = *dstWord;
  bits &= ~dstMask;
  if (*srcWord & srcMask) {
    bits |= dstMask;
  }
  *dstWord = bits;
}

MOZ_ALWAYS_INLINE void js::gc::ChunkMarkBitmap::unmark(const void* cell) {
  unmarkOneBit(cell, ColorBit::BlackBit);
  unmarkOneBit(cell, ColorBit::GrayOrBlackBit);
}

MOZ_ALWAYS_INLINE void js::gc::ChunkMarkBitmap::unmarkOneBit(
    const void* cell, ColorBit colorBit) {
  Word* word;
  uintptr_t mask;
  uintptr_t bits;
  getMarkWordAndMask(cell, colorBit, &word, &mask);
  bits = *word;
  *word = bits & ~mask;
}

inline js::gc::AtomicBitmapWord* js::gc::ChunkMarkBitmap::arenaBits(
    Arena* arena) {
  static_assert(
      ArenaBitmapBits == ArenaBitmapWords * JS_BITS_PER_WORD,
      "We assume that the part of the bitmap corresponding to the arena "
      "has the exact number of words so we do not need to deal with a word "
      "that covers bits from two arenas.");

  Word* word;
  uintptr_t unused;
  getMarkWordAndMask(arena, ColorBit::BlackBit, &word, &unused);
  return word;
}

inline void js::gc::ChunkMarkBitmap::copyFrom(const ChunkMarkBitmap& other) {
  Bitmap::copyFrom(other);
}

template <size_t N>
void js::gc::AtomicBitmap<N>::copyFrom(const AtomicBitmap& other) {
  for (size_t i = 0; i < WordCount; i++) {
    bitmap[i] = uintptr_t(other.bitmap[i]);
  }
}

template <size_t N>
void js::gc::AtomicBitmap<N>::clear() {
  for (size_t i = 0; i < WordCount; i++) {
    bitmap[i] = 0;
  }
}

template <size_t N>
bool js::gc::AtomicBitmap<N>::isEmpty() const {
  for (size_t i = 0; i < WordCount; i++) {
    if (bitmap[i]) {
      return false;
    }
  }

  return true;
}

bool js::gc::TenuredCell::markIfUnmarked(MarkColor color /* = Black */) const {
  return chunk()->markBits.markIfUnmarked(this, color);
}

bool js::gc::TenuredCell::markIfUnmarkedThreadSafe(MarkColor color) const {
  return chunk()->markBits.markIfUnmarkedThreadSafe(this, color);
}

void js::gc::TenuredCell::markBlack() const {
  chunk()->markBits.markBlack(this);
}

void js::gc::TenuredCell::markBlackAtomic() const {
  chunk()->markBits.markBlackAtomic(this);
}

void js::gc::TenuredCell::copyMarkBitsFrom(const TenuredCell* src) {
  ChunkMarkBitmap& markBits = chunk()->markBits;
  markBits.copyMarkBit(this, src, ColorBit::BlackBit);
  markBits.copyMarkBit(this, src, ColorBit::GrayOrBlackBit);
}

void js::gc::TenuredCell::unmark() { chunk()->markBits.unmark(this); }

#endif

Messung V0.5 in Prozent
C=90 H=95 G=92

¤ Dauer der Verarbeitung: 0.19 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.