Line data Source code
1 : // Copyright 2016 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_MANAGED_H_
6 : #define V8_MANAGED_H_
7 :
8 : #include "src/factory.h"
9 : #include "src/global-handles.h"
10 : #include "src/handles.h"
11 : #include "src/isolate.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 : // An object that wraps a pointer to a C++ object and manages its lifetime.
16 : // The C++ object will be deleted when the managed wrapper object is
17 : // garbage collected, or, last resort, if the isolate is torn down before GC,
18 : // as part of Isolate::Dispose().
19 : // Managed<CppType> may be used polymorphically as Foreign, where the held
20 : // address is typed as CppType**. The double indirection is due to the
21 : // use, by Managed, of Isolate::ManagedObjectFinalizer, which has a CppType*
22 : // first field.
23 : template <class CppType>
24 : class Managed : public Foreign {
25 : public:
26 : V8_INLINE CppType* get() {
27 153295 : return *(reinterpret_cast<CppType**>(foreign_address()));
28 : }
29 :
30 : static Managed<CppType>* cast(Object* obj) {
31 : SLOW_DCHECK(obj->IsForeign());
32 : return reinterpret_cast<Managed<CppType>*>(obj);
33 : }
34 :
35 20982 : static Handle<Managed<CppType>> New(Isolate* isolate, CppType* ptr) {
36 : Isolate::ManagedObjectFinalizer* node =
37 : isolate->RegisterForReleaseAtTeardown(ptr,
38 20982 : Managed<CppType>::NativeDelete);
39 : Handle<Managed<CppType>> handle = Handle<Managed<CppType>>::cast(
40 20982 : isolate->factory()->NewForeign(reinterpret_cast<Address>(node)));
41 20982 : RegisterWeakCallbackForDelete(isolate, handle);
42 20982 : return handle;
43 : }
44 :
45 : private:
46 41964 : static void RegisterWeakCallbackForDelete(Isolate* isolate,
47 : Handle<Managed<CppType>> handle) {
48 : Handle<Object> global_handle = isolate->global_handles()->Create(*handle);
49 20982 : GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(),
50 : &Managed<CppType>::GCDelete,
51 : v8::WeakCallbackType::kFinalizer);
52 20982 : }
53 :
54 12394 : static void GCDelete(const v8::WeakCallbackInfo<void>& data) {
55 : Managed<CppType>** p =
56 : reinterpret_cast<Managed<CppType>**>(data.GetParameter());
57 :
58 12394 : Isolate::ManagedObjectFinalizer* finalizer = (*p)->GetFinalizer();
59 :
60 : Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
61 6197 : finalizer->Dispose();
62 6197 : isolate->UnregisterFromReleaseAtTeardown(&finalizer);
63 :
64 6197 : (*p)->set_foreign_address(static_cast<Address>(nullptr));
65 6197 : GlobalHandles::Destroy(reinterpret_cast<Object**>(p));
66 6197 : }
67 :
68 20891 : static void NativeDelete(void* value) {
69 : CppType* typed_value = reinterpret_cast<CppType*>(value);
70 20891 : delete typed_value;
71 20891 : }
72 :
73 : Isolate::ManagedObjectFinalizer* GetFinalizer() {
74 : return reinterpret_cast<Isolate::ManagedObjectFinalizer*>(
75 : foreign_address());
76 : }
77 : };
78 : } // namespace internal
79 : } // namespace v8
80 :
81 : #endif // V8_MANAGED_H_
|