• 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/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