Kaido Kert | f309f9a | 2021-04-30 12:09:15 -0700 | [diff] [blame] | 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 | |
| 14 | namespace v8 { |
| 15 | namespace internal { |
| 16 | |
| 17 | class NativeContext; |
| 18 | class 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 |
| 24 | class JSFinalizationRegistry : public JSObject { |
| 25 | public: |
| 26 | DECL_PRINTER(JSFinalizationRegistry) |
| 27 | EXPORT_DECL_VERIFIER(JSFinalizationRegistry) |
| 28 | DECL_CAST(JSFinalizationRegistry) |
| 29 | |
| 30 | DECL_ACCESSORS(native_context, NativeContext) |
| 31 | DECL_ACCESSORS(cleanup, Object) |
| 32 | |
| 33 | DECL_ACCESSORS(active_cells, HeapObject) |
| 34 | DECL_ACCESSORS(cleared_cells, HeapObject) |
| 35 | DECL_ACCESSORS(key_map, Object) |
| 36 | |
| 37 | DECL_ACCESSORS(next_dirty, Object) |
| 38 | |
| 39 | DECL_INT_ACCESSORS(flags) |
| 40 | |
| 41 | DECL_BOOLEAN_ACCESSORS(scheduled_for_cleanup) |
| 42 | |
| 43 | class BodyDescriptor; |
| 44 | |
| 45 | inline static void RegisterWeakCellWithUnregisterToken( |
| 46 | Handle<JSFinalizationRegistry> finalization_registry, |
| 47 | Handle<WeakCell> weak_cell, Isolate* isolate); |
| 48 | inline static bool Unregister( |
| 49 | Handle<JSFinalizationRegistry> finalization_registry, |
| 50 | Handle<JSReceiver> unregister_token, Isolate* isolate); |
| 51 | |
| 52 | // RemoveUnregisterToken is called from both Unregister and during GC. Since |
| 53 | // it modifies slots in key_map and WeakCells and the normal write barrier is |
| 54 | // disabled during GC, we need to tell the GC about the modified slots via the |
| 55 | // gc_notify_updated_slot function. |
| 56 | template <typename MatchCallback, typename GCNotifyUpdatedSlotCallback> |
| 57 | inline bool RemoveUnregisterToken( |
| 58 | JSReceiver unregister_token, Isolate* isolate, |
| 59 | MatchCallback match_callback, |
| 60 | GCNotifyUpdatedSlotCallback gc_notify_updated_slot); |
| 61 | |
| 62 | // Returns true if the cleared_cells list is non-empty. |
| 63 | inline bool NeedsCleanup() const; |
| 64 | |
| 65 | // Remove the already-popped weak_cell from its unregister token linked list, |
| 66 | // as well as removing the entry from the key map if it is the only WeakCell |
| 67 | // with its unregister token. This method cannot GC and does not shrink the |
| 68 | // key map. Asserts that weak_cell has a non-undefined unregister token. |
| 69 | // |
| 70 | // It takes raw Addresses because it is called from CSA and Torque. |
| 71 | V8_EXPORT_PRIVATE static void RemoveCellFromUnregisterTokenMap( |
| 72 | Isolate* isolate, Address raw_finalization_registry, |
| 73 | Address raw_weak_cell); |
| 74 | |
| 75 | // Layout description. |
| 76 | DEFINE_FIELD_OFFSET_CONSTANTS( |
| 77 | JSObject::kHeaderSize, TORQUE_GENERATED_JS_FINALIZATION_REGISTRY_FIELDS) |
| 78 | |
| 79 | // Bitfields in flags. |
| 80 | DEFINE_TORQUE_GENERATED_FINALIZATION_REGISTRY_FLAGS() |
| 81 | |
| 82 | OBJECT_CONSTRUCTORS(JSFinalizationRegistry, JSObject); |
| 83 | }; |
| 84 | |
| 85 | // Internal object for storing weak references in JSFinalizationRegistry. |
| 86 | class WeakCell : public TorqueGeneratedWeakCell<WeakCell, HeapObject> { |
| 87 | public: |
| 88 | DECL_PRINTER(WeakCell) |
| 89 | EXPORT_DECL_VERIFIER(WeakCell) |
| 90 | |
| 91 | class BodyDescriptor; |
| 92 | |
| 93 | // Provide relaxed load access to target field. |
| 94 | inline HeapObject relaxed_target() const; |
| 95 | |
| 96 | // Nullify is called during GC and it modifies the pointers in WeakCell and |
| 97 | // JSFinalizationRegistry. Thus we need to tell the GC about the modified |
| 98 | // slots via the gc_notify_updated_slot function. The normal write barrier is |
| 99 | // not enough, since it's disabled before GC. |
| 100 | template <typename GCNotifyUpdatedSlotCallback> |
| 101 | inline void Nullify(Isolate* isolate, |
| 102 | GCNotifyUpdatedSlotCallback gc_notify_updated_slot); |
| 103 | |
| 104 | inline void RemoveFromFinalizationRegistryCells(Isolate* isolate); |
| 105 | |
| 106 | TQ_OBJECT_CONSTRUCTORS(WeakCell) |
| 107 | }; |
| 108 | |
| 109 | class JSWeakRef : public TorqueGeneratedJSWeakRef<JSWeakRef, JSObject> { |
| 110 | public: |
| 111 | DECL_PRINTER(JSWeakRef) |
| 112 | EXPORT_DECL_VERIFIER(JSWeakRef) |
| 113 | |
| 114 | class BodyDescriptor; |
| 115 | |
| 116 | TQ_OBJECT_CONSTRUCTORS(JSWeakRef) |
| 117 | }; |
| 118 | |
| 119 | } // namespace internal |
| 120 | } // namespace v8 |
| 121 | |
| 122 | #include "src/objects/object-macros-undef.h" |
| 123 | |
| 124 | #endif // V8_OBJECTS_JS_WEAK_REFS_H_ |