• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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