1 // Copyright 2020 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_HANDLES_PERSISTENT_HANDLES_H_ 6 #define V8_HANDLES_PERSISTENT_HANDLES_H_ 7 8 #include <vector> 9 10 #include "include/v8-internal.h" 11 #include "src/api/api.h" 12 #include "src/base/macros.h" 13 #include "src/execution/isolate.h" 14 #include "src/objects/visitors.h" 15 #include "testing/gtest/include/gtest/gtest_prod.h" // nogncheck 16 17 namespace v8 { 18 namespace internal { 19 20 class Heap; 21 22 // PersistentHandles serves as a container for handles that can be passed back 23 // and forth between threads. Allocation and deallocation of this class is 24 // thread-safe and the isolate tracks all PersistentHandles containers. 25 class PersistentHandles { 26 public: 27 V8_EXPORT_PRIVATE explicit PersistentHandles(Isolate* isolate); 28 V8_EXPORT_PRIVATE ~PersistentHandles(); 29 30 PersistentHandles(const PersistentHandles&) = delete; 31 PersistentHandles& operator=(const PersistentHandles&) = delete; 32 33 V8_EXPORT_PRIVATE void Iterate(RootVisitor* visitor); 34 35 template <typename T> NewHandle(T obj)36 Handle<T> NewHandle(T obj) { 37 #ifdef DEBUG 38 CheckOwnerIsNotParked(); 39 #endif 40 return Handle<T>(GetHandle(obj.ptr())); 41 } 42 43 template <typename T> NewHandle(Handle<T> obj)44 Handle<T> NewHandle(Handle<T> obj) { 45 return NewHandle(*obj); 46 } 47 48 #ifdef DEBUG 49 V8_EXPORT_PRIVATE bool Contains(Address* location); 50 #endif 51 52 private: 53 void AddBlock(); 54 V8_EXPORT_PRIVATE Address* GetHandle(Address value); 55 56 #ifdef DEBUG 57 void Attach(LocalHeap* local_heap); 58 void Detach(); 59 V8_EXPORT_PRIVATE void CheckOwnerIsNotParked(); 60 61 LocalHeap* owner_ = nullptr; 62 63 #else Attach(LocalHeap *)64 void Attach(LocalHeap*) {} Detach()65 void Detach() {} 66 #endif 67 68 Isolate* isolate_; 69 std::vector<Address*> blocks_; 70 71 Address* block_next_; 72 Address* block_limit_; 73 74 PersistentHandles* prev_; 75 PersistentHandles* next_; 76 77 #ifdef DEBUG 78 std::set<Address*> ordered_blocks_; 79 #endif 80 81 friend class HandleScopeImplementer; 82 friend class LocalHeap; 83 friend class PersistentHandlesList; 84 85 FRIEND_TEST(PersistentHandlesTest, OrderOfBlocks); 86 }; 87 88 class PersistentHandlesList { 89 public: PersistentHandlesList()90 PersistentHandlesList() : persistent_handles_head_(nullptr) {} 91 92 void Iterate(RootVisitor* visitor, Isolate* isolate); 93 94 private: 95 void Add(PersistentHandles* persistent_handles); 96 void Remove(PersistentHandles* persistent_handles); 97 98 base::Mutex persistent_handles_mutex_; 99 PersistentHandles* persistent_handles_head_; 100 101 friend class PersistentHandles; 102 }; 103 104 // PersistentHandlesScope sets up a scope in which all created main thread 105 // handles become persistent handles that can be sent to another thread. 106 class V8_NODISCARD PersistentHandlesScope { 107 public: 108 V8_EXPORT_PRIVATE explicit PersistentHandlesScope(Isolate* isolate); 109 V8_EXPORT_PRIVATE ~PersistentHandlesScope(); 110 111 // Moves all blocks of this scope into PersistentHandles and returns it. 112 V8_EXPORT_PRIVATE std::unique_ptr<PersistentHandles> Detach(); 113 114 private: 115 Address* prev_limit_; 116 Address* prev_next_; 117 HandleScopeImplementer* const impl_; 118 119 #ifdef DEBUG 120 bool handles_detached_ = false; 121 int prev_level_; 122 #endif 123 }; 124 125 } // namespace internal 126 } // namespace v8 127 128 #endif // V8_HANDLES_PERSISTENT_HANDLES_H_ 129