1// Copyright 2018 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_OBJECTS_JS_WEAK_REFS_H_
6#define V8_OBJECTS_JS_WEAK_REFS_H_
7
8#include "src/objects/js-objects.h"
9#include "torque-generated/bit-fields.h"
10
11// Has to be the last include (doesn't have include guards):
12#include "src/objects/object-macros.h"
13
14namespace v8 {
15namespace internal {
16
17class NativeContext;
18class WeakCell;
19
20#include "torque-generated/src/objects/js-weak-refs-tq.inc"
21
22// FinalizationRegistry object from the JS Weak Refs spec proposal:
23// https://github.com/tc39/proposal-weakrefs
24class JSFinalizationRegistry
25    : public TorqueGeneratedJSFinalizationRegistry<JSFinalizationRegistry,
26                                                   JSObject> {
27 public:
28  DECL_PRINTER(JSFinalizationRegistry)
29  EXPORT_DECL_VERIFIER(JSFinalizationRegistry)
30
31  DECL_BOOLEAN_ACCESSORS(scheduled_for_cleanup)
32
33  class BodyDescriptor;
34
35  inline static void RegisterWeakCellWithUnregisterToken(
36      Handle<JSFinalizationRegistry> finalization_registry,
37      Handle<WeakCell> weak_cell, Isolate* isolate);
38  inline static bool Unregister(
39      Handle<JSFinalizationRegistry> finalization_registry,
40      Handle<HeapObject> unregister_token, Isolate* isolate);
41
42  // RemoveUnregisterToken is called from both Unregister and during GC. Since
43  // it modifies slots in key_map and WeakCells and the normal write barrier is
44  // disabled during GC, we need to tell the GC about the modified slots via the
45  // gc_notify_updated_slot function.
46  enum RemoveUnregisterTokenMode {
47    kRemoveMatchedCellsFromRegistry,
48    kKeepMatchedCellsInRegistry
49  };
50  template <typename GCNotifyUpdatedSlotCallback>
51  inline bool RemoveUnregisterToken(
52      HeapObject unregister_token, Isolate* isolate,
53      RemoveUnregisterTokenMode removal_mode,
54      GCNotifyUpdatedSlotCallback gc_notify_updated_slot);
55
56  // Returns true if the cleared_cells list is non-empty.
57  inline bool NeedsCleanup() const;
58
59  // Remove the already-popped weak_cell from its unregister token linked list,
60  // as well as removing the entry from the key map if it is the only WeakCell
61  // with its unregister token. This method cannot GC and does not shrink the
62  // key map. Asserts that weak_cell has a non-undefined unregister token.
63  //
64  // It takes raw Addresses because it is called from CSA and Torque.
65  V8_EXPORT_PRIVATE static void RemoveCellFromUnregisterTokenMap(
66      Isolate* isolate, Address raw_finalization_registry,
67      Address raw_weak_cell);
68
69  // Bitfields in flags.
70  DEFINE_TORQUE_GENERATED_FINALIZATION_REGISTRY_FLAGS()
71
72  TQ_OBJECT_CONSTRUCTORS(JSFinalizationRegistry)
73};
74
75// Internal object for storing weak references in JSFinalizationRegistry.
76class WeakCell : public TorqueGeneratedWeakCell<WeakCell, HeapObject> {
77 public:
78  EXPORT_DECL_VERIFIER(WeakCell)
79
80  class BodyDescriptor;
81
82  // Provide relaxed load access to target field.
83  inline HeapObject relaxed_target() const;
84
85  // Provide relaxed load access to the unregister token field.
86  inline HeapObject relaxed_unregister_token() const;
87
88  // Nullify is called during GC and it modifies the pointers in WeakCell and
89  // JSFinalizationRegistry. Thus we need to tell the GC about the modified
90  // slots via the gc_notify_updated_slot function. The normal write barrier is
91  // not enough, since it's disabled before GC.
92  template <typename GCNotifyUpdatedSlotCallback>
93  inline void Nullify(Isolate* isolate,
94                      GCNotifyUpdatedSlotCallback gc_notify_updated_slot);
95
96  inline void RemoveFromFinalizationRegistryCells(Isolate* isolate);
97
98  TQ_OBJECT_CONSTRUCTORS(WeakCell)
99};
100
101class JSWeakRef : public TorqueGeneratedJSWeakRef<JSWeakRef, JSObject> {
102 public:
103  DECL_PRINTER(JSWeakRef)
104  EXPORT_DECL_VERIFIER(JSWeakRef)
105
106  class BodyDescriptor;
107
108  TQ_OBJECT_CONSTRUCTORS(JSWeakRef)
109};
110
111}  // namespace internal
112}  // namespace v8
113
114#include "src/objects/object-macros-undef.h"
115
116#endif  // V8_OBJECTS_JS_WEAK_REFS_H_
117