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