OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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_VM_STORE_BUFFER_H_ | 5 #ifndef RUNTIME_VM_STORE_BUFFER_H_ |
6 #define RUNTIME_VM_STORE_BUFFER_H_ | 6 #define RUNTIME_VM_STORE_BUFFER_H_ |
7 | 7 |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
10 | 10 |
11 namespace dart { | 11 namespace dart { |
12 | 12 |
13 // Forward declarations. | 13 // Forward declarations. |
14 class Isolate; | 14 class Isolate; |
15 class Mutex; | 15 class Mutex; |
16 class RawObject; | 16 class RawObject; |
17 | 17 |
18 // A set of RawObject*. Must be emptied before destruction (using Pop/Reset). | 18 // A set of RawObject*. Must be emptied before destruction (using Pop/Reset). |
19 template<int Size> | 19 template <int Size> |
20 class PointerBlock { | 20 class PointerBlock { |
21 public: | 21 public: |
22 enum { kSize = Size }; | 22 enum { kSize = Size }; |
23 | 23 |
24 void Reset() { | 24 void Reset() { |
25 top_ = 0; | 25 top_ = 0; |
26 next_ = NULL; | 26 next_ = NULL; |
27 } | 27 } |
28 | 28 |
29 PointerBlock<Size>* next() const { return next_; } | 29 PointerBlock<Size>* next() const { return next_; } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 private: | 61 private: |
62 PointerBlock() : next_(NULL), top_(0) {} | 62 PointerBlock() : next_(NULL), top_(0) {} |
63 ~PointerBlock() { | 63 ~PointerBlock() { |
64 ASSERT(IsEmpty()); // Guard against unintentionally discarding pointers. | 64 ASSERT(IsEmpty()); // Guard against unintentionally discarding pointers. |
65 } | 65 } |
66 | 66 |
67 PointerBlock<Size>* next_; | 67 PointerBlock<Size>* next_; |
68 int32_t top_; | 68 int32_t top_; |
69 RawObject* pointers_[kSize]; | 69 RawObject* pointers_[kSize]; |
70 | 70 |
71 template<int> friend class BlockStack; | 71 template <int> |
| 72 friend class BlockStack; |
72 | 73 |
73 DISALLOW_COPY_AND_ASSIGN(PointerBlock); | 74 DISALLOW_COPY_AND_ASSIGN(PointerBlock); |
74 }; | 75 }; |
75 | 76 |
76 | 77 |
77 // A synchronized collection of pointer blocks of a particular size. | 78 // A synchronized collection of pointer blocks of a particular size. |
78 // This class is meant to be used as a base (note PushBlockImpl is protected). | 79 // This class is meant to be used as a base (note PushBlockImpl is protected). |
79 // The global list of cached empty blocks is currently per-size. | 80 // The global list of cached empty blocks is currently per-size. |
80 template<int BlockSize> | 81 template <int BlockSize> |
81 class BlockStack { | 82 class BlockStack { |
82 public: | 83 public: |
83 typedef PointerBlock<BlockSize> Block; | 84 typedef PointerBlock<BlockSize> Block; |
84 | 85 |
85 BlockStack(); | 86 BlockStack(); |
86 ~BlockStack(); | 87 ~BlockStack(); |
87 static void InitOnce(); | 88 static void InitOnce(); |
88 static void ShutDown(); | 89 static void ShutDown(); |
89 | 90 |
90 // Partially filled blocks can be reused, and there is an "inifite" supply | 91 // Partially filled blocks can be reused, and there is an "inifite" supply |
(...skipping 14 matching lines...) Expand all Loading... |
105 protected: | 106 protected: |
106 class List { | 107 class List { |
107 public: | 108 public: |
108 List() : head_(NULL), length_(0) {} | 109 List() : head_(NULL), length_(0) {} |
109 ~List(); | 110 ~List(); |
110 void Push(Block* block); | 111 void Push(Block* block); |
111 Block* Pop(); | 112 Block* Pop(); |
112 intptr_t length() const { return length_; } | 113 intptr_t length() const { return length_; } |
113 bool IsEmpty() const { return head_ == NULL; } | 114 bool IsEmpty() const { return head_ == NULL; } |
114 Block* PopAll(); | 115 Block* PopAll(); |
| 116 |
115 private: | 117 private: |
116 Block* head_; | 118 Block* head_; |
117 intptr_t length_; | 119 intptr_t length_; |
118 DISALLOW_COPY_AND_ASSIGN(List); | 120 DISALLOW_COPY_AND_ASSIGN(List); |
119 }; | 121 }; |
120 | 122 |
121 // Adds and transfers ownership of the block to the buffer. | 123 // Adds and transfers ownership of the block to the buffer. |
122 void PushBlockImpl(Block* block); | 124 void PushBlockImpl(Block* block); |
123 | 125 |
124 // If needed, trims the global cache of empty blocks. | 126 // If needed, trims the global cache of empty blocks. |
(...skipping 12 matching lines...) Expand all Loading... |
137 DISALLOW_COPY_AND_ASSIGN(BlockStack); | 139 DISALLOW_COPY_AND_ASSIGN(BlockStack); |
138 }; | 140 }; |
139 | 141 |
140 | 142 |
141 static const int kStoreBufferBlockSize = 1024; | 143 static const int kStoreBufferBlockSize = 1024; |
142 class StoreBuffer : public BlockStack<kStoreBufferBlockSize> { | 144 class StoreBuffer : public BlockStack<kStoreBufferBlockSize> { |
143 public: | 145 public: |
144 // Interrupt when crossing this threshold of non-empty blocks in the buffer. | 146 // Interrupt when crossing this threshold of non-empty blocks in the buffer. |
145 static const intptr_t kMaxNonEmpty = 100; | 147 static const intptr_t kMaxNonEmpty = 100; |
146 | 148 |
147 enum ThresholdPolicy { | 149 enum ThresholdPolicy { kCheckThreshold, kIgnoreThreshold }; |
148 kCheckThreshold, | |
149 kIgnoreThreshold | |
150 }; | |
151 | 150 |
152 // Adds and transfers ownership of the block to the buffer. Optionally | 151 // Adds and transfers ownership of the block to the buffer. Optionally |
153 // checks the number of non-empty blocks for overflow, and schedules an | 152 // checks the number of non-empty blocks for overflow, and schedules an |
154 // interrupt on the current isolate if so. | 153 // interrupt on the current isolate if so. |
155 void PushBlock(Block* block, ThresholdPolicy policy); | 154 void PushBlock(Block* block, ThresholdPolicy policy); |
156 | 155 |
157 // Check whether non-empty blocks have exceeded kMaxNonEmpty (but takes no | 156 // Check whether non-empty blocks have exceeded kMaxNonEmpty (but takes no |
158 // action). | 157 // action). |
159 bool Overflowed(); | 158 bool Overflowed(); |
160 }; | 159 }; |
161 | 160 |
162 | 161 |
163 typedef StoreBuffer::Block StoreBufferBlock; | 162 typedef StoreBuffer::Block StoreBufferBlock; |
164 | 163 |
165 | 164 |
166 static const int kMarkingStackBlockSize = 64; | 165 static const int kMarkingStackBlockSize = 64; |
167 class MarkingStack : public BlockStack<kMarkingStackBlockSize> { | 166 class MarkingStack : public BlockStack<kMarkingStackBlockSize> { |
168 public: | 167 public: |
169 // Adds and transfers ownership of the block to the buffer. | 168 // Adds and transfers ownership of the block to the buffer. |
170 void PushBlock(Block* block) { | 169 void PushBlock(Block* block) { |
171 BlockStack<Block::kSize>::PushBlockImpl(block); | 170 BlockStack<Block::kSize>::PushBlockImpl(block); |
172 } | 171 } |
173 }; | 172 }; |
174 | 173 |
175 | 174 |
176 } // namespace dart | 175 } // namespace dart |
177 | 176 |
178 #endif // RUNTIME_VM_STORE_BUFFER_H_ | 177 #endif // RUNTIME_VM_STORE_BUFFER_H_ |
OLD | NEW |