OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef RUNTIME_BIN_REFERENCE_COUNTING_H_ | 5 #ifndef RUNTIME_BIN_REFERENCE_COUNTING_H_ |
6 #define RUNTIME_BIN_REFERENCE_COUNTING_H_ | 6 #define RUNTIME_BIN_REFERENCE_COUNTING_H_ |
7 | 7 |
8 #include "vm/atomic.h" | 8 #include "vm/atomic.h" |
9 | 9 |
10 namespace dart { | 10 namespace dart { |
(...skipping 15 matching lines...) Expand all Loading... |
26 // | 26 // |
27 // void DoStuffWithAFoo() { | 27 // void DoStuffWithAFoo() { |
28 // Foo* foo = new Foo(); // Reference count starts at 1, so no explicit | 28 // Foo* foo = new Foo(); // Reference count starts at 1, so no explicit |
29 // // call to Retain is needed after allocation. | 29 // // call to Retain is needed after allocation. |
30 // ... | 30 // ... |
31 // foo->Release(); | 31 // foo->Release(); |
32 // } | 32 // } |
33 template <class Derived> | 33 template <class Derived> |
34 class ReferenceCounted { | 34 class ReferenceCounted { |
35 public: | 35 public: |
36 ReferenceCounted() : ref_count_(1) {} | 36 ReferenceCounted() : ref_count_(1) { |
| 37 #if defined(DEBUG) |
| 38 AtomicOperations::FetchAndIncrement(&instances_); |
| 39 #endif // defined(DEBUG) |
| 40 } |
37 | 41 |
38 ~ReferenceCounted() { ASSERT(ref_count_ == 0); } | 42 virtual ~ReferenceCounted() { |
| 43 ASSERT(ref_count_ == 0); |
| 44 #if defined(DEBUG) |
| 45 AtomicOperations::FetchAndDecrement(&instances_); |
| 46 #endif // defined(DEBUG) |
| 47 } |
39 | 48 |
40 void Retain() { | 49 void Retain() { |
41 uintptr_t old = AtomicOperations::FetchAndIncrement(&ref_count_); | 50 intptr_t old = AtomicOperations::FetchAndIncrement(&ref_count_); |
42 ASSERT(old > 0); | 51 ASSERT(old > 0); |
43 } | 52 } |
44 | 53 |
45 void Release() { | 54 void Release() { |
46 uintptr_t old = AtomicOperations::FetchAndDecrement(&ref_count_); | 55 intptr_t old = AtomicOperations::FetchAndDecrement(&ref_count_); |
47 ASSERT(old > 0); | 56 ASSERT(old > 0); |
48 if (old == 1) { | 57 if (old == 1) { |
49 delete static_cast<Derived*>(this); | 58 delete static_cast<Derived*>(this); |
50 } | 59 } |
51 } | 60 } |
52 | 61 |
| 62 #if defined(DEBUG) |
| 63 static intptr_t instances() { return instances_; } |
| 64 #endif // defined(DEBUG) |
| 65 |
53 private: | 66 private: |
54 uintptr_t ref_count_; | 67 #if defined(DEBUG) |
| 68 static intptr_t instances_; |
| 69 #endif // defined(DEBUG) |
| 70 |
| 71 intptr_t ref_count_; |
55 | 72 |
56 // These are used only in the ASSERT below in RefCntReleaseScope. | 73 // These are used only in the ASSERT below in RefCntReleaseScope. |
57 uintptr_t ref_count() const { return ref_count_; } | 74 intptr_t ref_count() const { return ref_count_; } |
58 friend class RefCntReleaseScope<Derived>; | 75 friend class RefCntReleaseScope<Derived>; |
59 DISALLOW_COPY_AND_ASSIGN(ReferenceCounted); | 76 DISALLOW_COPY_AND_ASSIGN(ReferenceCounted); |
60 }; | 77 }; |
61 | 78 |
| 79 #if defined(DEBUG) |
| 80 template <class Derived> |
| 81 intptr_t ReferenceCounted<Derived>::instances_ = 0; |
| 82 #endif |
| 83 |
62 // Creates a scope at the end of which a reference counted object is | 84 // Creates a scope at the end of which a reference counted object is |
63 // Released. This is useful for reference counted objects recieved by the IO | 85 // Released. This is useful for reference counted objects recieved by the IO |
64 // Service, which have already been Retained E.g.: | 86 // Service, which have already been Retained E.g.: |
65 // | 87 // |
66 // CObject* Foo::FooRequest(const CObjectArray& request) { | 88 // CObject* Foo::FooRequest(const CObjectArray& request) { |
67 // Foo* foo = CObjectToFoo(request[0]); | 89 // Foo* foo = CObjectToFoo(request[0]); |
68 // RefCntReleaseScope<Foo> rs(foo); | 90 // RefCntReleaseScope<Foo> rs(foo); |
69 // ... | 91 // ... |
70 // } | 92 // } |
71 template <class Target> | 93 template <class Target> |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 ReferenceCounted<Target>* target_; | 165 ReferenceCounted<Target>* target_; |
144 | 166 |
145 DISALLOW_ALLOCATION(); | 167 DISALLOW_ALLOCATION(); |
146 DISALLOW_COPY_AND_ASSIGN(RetainedPointer); | 168 DISALLOW_COPY_AND_ASSIGN(RetainedPointer); |
147 }; | 169 }; |
148 | 170 |
149 } // namespace bin | 171 } // namespace bin |
150 } // namespace dart | 172 } // namespace dart |
151 | 173 |
152 #endif // RUNTIME_BIN_REFERENCE_COUNTING_H_ | 174 #endif // RUNTIME_BIN_REFERENCE_COUNTING_H_ |
OLD | NEW |