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

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


/*
 * FinalizationRegistry objects allow a program to register to receive a
 * callback after a 'target' object dies. The callback is passed a 'held value'
 * (that hopefully doesn't entrain the target). An 'unregister token' is an
 * object which can be used to remove multiple previous registrations in one go.
 *
 * To arrange this, the following data structures are used:
 *
 *   +---------------------------------------+-------------------------------+
 *   |   FinalizationRegistry compartment    |   Target zone / compartment   |
 *   |                                       |                               |
 *   |     +------------------------------+  |     +------------------+      |
 *   |  +--+    FinalizationRegistry      |  |     |       Zone       |      |
 *   |  |  +---+----------------+---------+  |     +---------+--------+      |
 *   |  |      |                |            |               |               |
 *   |  |      v                v            |               v               |
 *   |  |  +---+---+  +---------+---------+  |  +------------+------------+  |
 *   |  |  |Record |  |   Registrations   |  |  |  FinalizationObservers  |  |
 *   |  |  |Vector |  |        map        |  |  +------------+------------+  |
 *   |  |  +---+---+  +-------------------+  |               |               |
 *   |  |      |      |   Weak    :Records|  |               |               |
 *   |  |      |      | unregister:Vector |  |               v               |
 *   |  |      |      |   token   :       |  |  +------------+------------+  |
 *   |  |      |      +--------------+----+  |  |      RecordMap map      |  |
 *   |  |      |                     |       |  +-------------------------+  |
 *   |  |      |                     |       |  |  Target  : ObserverList |  |
 *   |  |      |                     |       |  |  object  :              |  |
 *   |  |    * v                   * v       |  +----+-------------+------+  |
 *   |  |  +-------------------------+-+ *   |       |             |         |
 *   |  |  | FinalizationRecordObject  +<--------------------------+         |
 *   |  |  +---------------------------+     |       |                       |
 *   |  |  | Queue                     +--+  |       v                       |
 *   |  |  +---------------------------+  |  |  +----+-----+                 |
 *   |  |  | Held value                |  |  |  |  Target  |                 |
 *   |  |  +---------------------------+  |  |  | GC thing |                 |
 *   |  |                                 |  |  +----------+                 |
 *   |  +--------------+   +--------------+  |                               |
 *   |                 |   |                 |                               |
 *   |                 v   v                 |                               |
 *   |      +----------+---+----------+      |                               |
 *   |      | FinalizationQueueObject |      |                               |
 *   |      +-------------------------+      |                               |
 *   |                                       |                               |
 *   +---------------------------------------+-------------------------------+
 *
 * A FinalizationRegistry consists of several parts:
 *  - the FinalizationRegistry object that consumers see
 *  - zero or more FinalizationRecordObjects representing registered targets
 *  - a FinalizationQueue containing records for targets that have died, used to
 *    queue and call the cleanup callbacks
 *  - a map tracking unregister tokens and their associated records
 *
 * Registering a target with a FinalizationRegistry creates a FinalizationRecord
 * containing a pointer to the queue and the heldValue. This is added to the
 * registry's vector of registered targets and also to a linked list of
 * finalization observers which is used to actually track the target.
 *
 * When a target is registered an unregister token may be supplied. If so, this
 * is also recorded by the registry and is stored in a map of registrations.
 * They keys of this map are weakly held and do not keep the unregister token
 * alive.
 *
 * When targets are unregistered, the registration is looked up in the
 * registrations map and the corresponding records are cleared.

 * The finalization observer lists are swept during GC to check for records
 * associated with dying targets. For such targets the associated record list is
 * processed and each record is added to the FinalizationQueueObject. At a later
 * time this causes the client's cleanup callback to be run.
 */


#ifndef builtin_FinalizationRegistryObject_h
#define builtin_FinalizationRegistryObject_h

#include "gc/Barrier.h"
#include "gc/FinalizationObservers.h"
#include "js/GCVector.h"
#include "vm/NativeObject.h"

namespace js {

class FinalizationRegistryObject;
class FinalizationRecordObject;
class FinalizationQueueObject;

using HandleFinalizationRegistryObject = Handle<FinalizationRegistryObject*>;
using HandleFinalizationRecordObject = Handle<FinalizationRecordObject*>;
using HandleFinalizationQueueObject = Handle<FinalizationQueueObject*>;
using RootedFinalizationRegistryObject = Rooted<FinalizationRegistryObject*>;
using RootedFinalizationRecordObject = Rooted<FinalizationRecordObject*>;
using RootedFinalizationQueueObject = Rooted<FinalizationQueueObject*>;

// A finalization record: a pair of finalization queue and held value.
//
// A finalization record represents the registered interest of a finalization
// registry in a target's finalization.
//
// Finalization records created in the 'registered' state but may be
// unregistered. This happens when:
//  - the heldValue is passed to the registry's cleanup callback
//  - the registry's unregister method removes the registration
//
// Finalization records are added to a per-zone record map. They are removed
// when the record is queued for cleanup, or if the interest in finalization is
// cancelled. See FinalizationObservers::shouldRemoveRecord for the possible
// reasons.

class FinalizationRecordObject : public gc::ObserverListObject {
  enum {
    QueueSlot = ObserverListObject::SlotCount,
    HeldValueSlot,
    DebugStateSlot,  // Used for assertions only.
    SlotCount
  };

 public:
  enum State { Unknown, InRecordMap, InQueue };

  static const JSClass class_;

  static FinalizationRecordObject* create(JSContext* cx,
                                          HandleFinalizationQueueObject queue,
                                          HandleValue heldValue);

  FinalizationQueueObject* queue() const;
  Value heldValue() const;
  bool isRegistered() const;

#ifdef DEBUG
  void setState(State state);
  State getState() const;
  bool isInRecordMap() const { return getState() == InRecordMap; }
  bool isInQueue() const { return getState() == InQueue; }
#endif

  void setInRecordMap(bool newValue);
  void setInQueue(bool newValue);
  void clear();

 private:
  static const JSClassOps classOps_;

  static void finalize(JS::GCContext* gcx, JSObject* obj);
};

using FinalizationRecordVector =
    GCVector<HeapPtr<FinalizationRecordObject*>, 1, js::CellAllocPolicy>;

// The JS FinalizationRegistry object itself.
class FinalizationRegistryObject : public NativeObject {
  enum { QueueSlot = 0, RegistrationsSlot, RecordsWithoutTokenSlot, SlotCount };

 public:
  using RegistrationsMap =
      GCHashMap<HeapPtr<Value>, FinalizationRecordVector, gc::WeakTargetHasher>;

  static const JSClass class_;
  static const JSClass protoClass_;

  FinalizationQueueObject* queue() const;
  RegistrationsMap* registrations() const;
  FinalizationRecordVector* recordsWithoutToken() const;

  void traceWeak(JSTracer* trc, bool* hasSymbolRegistrations);

  static bool unregisterRecord(FinalizationRecordObject* record);

 private:
  static const JSClassOps classOps_;
  static const ClassSpec classSpec_;
  static const JSFunctionSpec methods_[];
  static const JSPropertySpec properties_[];

  static bool construct(JSContext* cx, unsigned argc, Value* vp);
  static bool register_(JSContext* cx, unsigned argc, Value* vp);
  static bool unregister(JSContext* cx, unsigned argc, Value* vp);
  static bool cleanupSome(JSContext* cx, unsigned argc, Value* vp);

  static bool addRegistration(JSContext* cx,
                              HandleFinalizationRegistryObject registry,
                              HandleValue unregisterToken,
                              HandleFinalizationRecordObject record);
  static void removeRegistrationOnError(
      HandleFinalizationRegistryObject registry, HandleValue unregisterToken,
      HandleFinalizationRecordObject record);

  static bool preserveDOMWrapper(JSContext* cx, HandleObject obj);

  static void trace(JSTracer* trc, JSObject* obj);
  static void finalize(JS::GCContext* gcx, JSObject* obj);
};

// Contains information about the cleanup callback and the records queued to
// be cleaned up. This is not exposed to content JS.
class FinalizationQueueObject : public NativeObject {
  enum {
    CleanupCallbackSlot = 0,
    IncumbentGlobalRepresentative,
    RecordsToBeCleanedUpSlot,
    IsQueuedForCleanupSlot,
    DoCleanupFunctionSlot,
    HasRegistrySlot,
    SlotCount
  };

  enum DoCleanupFunctionSlots {
    DoCleanupFunction_QueueSlot = 0,
  };

 public:
  static const JSClass class_;

  JSObject* cleanupCallback() const;
  JSObject* getIncumbentGlobalRepresentative() const;
  bool hasRecordsToCleanUp() const;
  FinalizationRecordVector* recordsToBeCleanedUp() const;
  bool isQueuedForCleanup() const;
  JSFunction* doCleanupFunction() const;
  bool hasRegistry() const;

  void queueRecordToBeCleanedUp(FinalizationRecordObject* record);
  void setQueuedForCleanup(bool value);

  void setHasRegistry(bool newValue);
  void clear();

  static FinalizationQueueObject* create(JSContext* cx,
                                         HandleObject cleanupCallback);

  static bool cleanupQueuedRecords(JSContext* cx,
                                   HandleFinalizationQueueObject registry,
                                   HandleObject callback = nullptr);

 private:
  static const JSClassOps classOps_;

  static bool doCleanup(JSContext* cx, unsigned argc, Value* vp);

  static void trace(JSTracer* trc, JSObject* obj);
  static void finalize(JS::GCContext* gcx, JSObject* obj);
};

}  // namespace js

#endif /* builtin_FinalizationRegistryObject_h */

Messung V0.5 in Prozent
C=90 H=98 G=94

¤ Dauer der Verarbeitung: 0.9 Sekunden  ¤

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