OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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_PAGES_H_ | 5 #ifndef RUNTIME_VM_PAGES_H_ |
6 #define RUNTIME_VM_PAGES_H_ | 6 #define RUNTIME_VM_PAGES_H_ |
7 | 7 |
8 #include "vm/freelist.h" | 8 #include "vm/freelist.h" |
9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
10 #include "vm/lockers.h" | 10 #include "vm/lockers.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 | 21 |
22 // Forward declarations. | 22 // Forward declarations. |
23 class Heap; | 23 class Heap; |
24 class JSONObject; | 24 class JSONObject; |
25 class ObjectPointerVisitor; | 25 class ObjectPointerVisitor; |
26 class ObjectSet; | 26 class ObjectSet; |
27 | 27 |
28 // A page containing old generation objects. | 28 // A page containing old generation objects. |
29 class HeapPage { | 29 class HeapPage { |
30 public: | 30 public: |
31 enum PageType { | 31 enum PageType { kData = 0, kExecutable, kReadOnlyData, kNumPageTypes }; |
32 kData = 0, | |
33 kExecutable, | |
34 kReadOnlyData, | |
35 kNumPageTypes | |
36 }; | |
37 | 32 |
38 HeapPage* next() const { return next_; } | 33 HeapPage* next() const { return next_; } |
39 void set_next(HeapPage* next) { next_ = next; } | 34 void set_next(HeapPage* next) { next_ = next; } |
40 | 35 |
41 bool Contains(uword addr) { | 36 bool Contains(uword addr) { return memory_->Contains(addr); } |
42 return memory_->Contains(addr); | |
43 } | |
44 | 37 |
45 uword object_start() const { | 38 uword object_start() const { return memory_->start() + ObjectStartOffset(); } |
46 return memory_->start() + ObjectStartOffset(); | 39 uword object_end() const { return object_end_; } |
47 } | |
48 uword object_end() const { | |
49 return object_end_; | |
50 } | |
51 | 40 |
52 PageType type() const { | 41 PageType type() const { return type_; } |
53 return type_; | |
54 } | |
55 | 42 |
56 bool embedder_allocated() const { return memory_->embedder_allocated(); } | 43 bool embedder_allocated() const { return memory_->embedder_allocated(); } |
57 | 44 |
58 void VisitObjects(ObjectVisitor* visitor) const; | 45 void VisitObjects(ObjectVisitor* visitor) const; |
59 void VisitObjectPointers(ObjectPointerVisitor* visitor) const; | 46 void VisitObjectPointers(ObjectPointerVisitor* visitor) const; |
60 | 47 |
61 RawObject* FindObject(FindObjectVisitor* visitor) const; | 48 RawObject* FindObject(FindObjectVisitor* visitor) const; |
62 | 49 |
63 void WriteProtect(bool read_only); | 50 void WriteProtect(bool read_only); |
64 | 51 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 ~PageSpaceController(); | 117 ~PageSpaceController(); |
131 | 118 |
132 // Returns whether growing to 'after' should trigger a GC. | 119 // Returns whether growing to 'after' should trigger a GC. |
133 // This method can be called before allocation (e.g., pretenuring) or after | 120 // This method can be called before allocation (e.g., pretenuring) or after |
134 // (e.g., promotion), as it does not change the state of the controller. | 121 // (e.g., promotion), as it does not change the state of the controller. |
135 bool NeedsGarbageCollection(SpaceUsage after) const; | 122 bool NeedsGarbageCollection(SpaceUsage after) const; |
136 | 123 |
137 // Should be called after each collection to update the controller state. | 124 // Should be called after each collection to update the controller state. |
138 void EvaluateGarbageCollection(SpaceUsage before, | 125 void EvaluateGarbageCollection(SpaceUsage before, |
139 SpaceUsage after, | 126 SpaceUsage after, |
140 int64_t start, int64_t end); | 127 int64_t start, |
| 128 int64_t end); |
141 | 129 |
142 int64_t last_code_collection_in_us() { return last_code_collection_in_us_; } | 130 int64_t last_code_collection_in_us() { return last_code_collection_in_us_; } |
143 void set_last_code_collection_in_us(int64_t t) { | 131 void set_last_code_collection_in_us(int64_t t) { |
144 last_code_collection_in_us_ = t; | 132 last_code_collection_in_us_ = t; |
145 } | 133 } |
146 | 134 |
147 void set_last_usage(SpaceUsage current) { | 135 void set_last_usage(SpaceUsage current) { last_usage_ = current; } |
148 last_usage_ = current; | |
149 } | |
150 | 136 |
151 void Enable() { | 137 void Enable() { is_enabled_ = true; } |
152 is_enabled_ = true; | 138 void Disable() { is_enabled_ = false; } |
153 } | 139 bool is_enabled() { return is_enabled_; } |
154 void Disable() { | |
155 is_enabled_ = false; | |
156 } | |
157 bool is_enabled() { | |
158 return is_enabled_; | |
159 } | |
160 | 140 |
161 private: | 141 private: |
162 Heap* heap_; | 142 Heap* heap_; |
163 | 143 |
164 bool is_enabled_; | 144 bool is_enabled_; |
165 | 145 |
166 // Usage after last evaluated GC or last enabled. | 146 // Usage after last evaluated GC or last enabled. |
167 SpaceUsage last_usage_; | 147 SpaceUsage last_usage_; |
168 | 148 |
169 // Pages of capacity growth allowed before next GC is advised. | 149 // Pages of capacity growth allowed before next GC is advised. |
(...skipping 22 matching lines...) Expand all Loading... |
192 | 172 |
193 DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpaceController); | 173 DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpaceController); |
194 }; | 174 }; |
195 | 175 |
196 | 176 |
197 class PageSpace { | 177 class PageSpace { |
198 public: | 178 public: |
199 // TODO(iposva): Determine heap sizes and tune the page size accordingly. | 179 // TODO(iposva): Determine heap sizes and tune the page size accordingly. |
200 static const intptr_t kPageSizeInWords = 256 * KBInWords; | 180 static const intptr_t kPageSizeInWords = 256 * KBInWords; |
201 | 181 |
202 enum GrowthPolicy { | 182 enum GrowthPolicy { kControlGrowth, kForceGrowth }; |
203 kControlGrowth, | |
204 kForceGrowth | |
205 }; | |
206 | 183 |
207 PageSpace(Heap* heap, | 184 PageSpace(Heap* heap, |
208 intptr_t max_capacity_in_words, | 185 intptr_t max_capacity_in_words, |
209 intptr_t max_external_in_words); | 186 intptr_t max_external_in_words); |
210 ~PageSpace(); | 187 ~PageSpace(); |
211 | 188 |
212 uword TryAllocate(intptr_t size, | 189 uword TryAllocate(intptr_t size, |
213 HeapPage::PageType type = HeapPage::kData, | 190 HeapPage::PageType type = HeapPage::kData, |
214 GrowthPolicy growth_policy = kControlGrowth) { | 191 GrowthPolicy growth_policy = kControlGrowth) { |
215 bool is_protected = | 192 bool is_protected = |
216 (type == HeapPage::kExecutable) && FLAG_write_protect_code; | 193 (type == HeapPage::kExecutable) && FLAG_write_protect_code; |
217 bool is_locked = false; | 194 bool is_locked = false; |
218 return TryAllocateInternal( | 195 return TryAllocateInternal(size, type, growth_policy, is_protected, |
219 size, type, growth_policy, is_protected, is_locked); | 196 is_locked); |
220 } | 197 } |
221 | 198 |
222 bool NeedsGarbageCollection() const { | 199 bool NeedsGarbageCollection() const { |
223 return page_space_controller_.NeedsGarbageCollection(usage_) || | 200 return page_space_controller_.NeedsGarbageCollection(usage_) || |
224 NeedsExternalGC(); | 201 NeedsExternalGC(); |
225 } | 202 } |
226 | 203 |
227 int64_t UsedInWords() const { return usage_.used_in_words; } | 204 int64_t UsedInWords() const { return usage_.used_in_words; } |
228 int64_t CapacityInWords() const { | 205 int64_t CapacityInWords() const { |
229 MutexLocker ml(pages_lock_); | 206 MutexLocker ml(pages_lock_); |
230 return usage_.capacity_in_words; | 207 return usage_.capacity_in_words; |
231 } | 208 } |
232 void IncreaseCapacityInWords(intptr_t increase_in_words) { | 209 void IncreaseCapacityInWords(intptr_t increase_in_words) { |
233 MutexLocker ml(pages_lock_); | 210 MutexLocker ml(pages_lock_); |
234 IncreaseCapacityInWordsLocked(increase_in_words); | 211 IncreaseCapacityInWordsLocked(increase_in_words); |
235 } | 212 } |
236 void IncreaseCapacityInWordsLocked(intptr_t increase_in_words) { | 213 void IncreaseCapacityInWordsLocked(intptr_t increase_in_words) { |
237 DEBUG_ASSERT(pages_lock_->IsOwnedByCurrentThread()); | 214 DEBUG_ASSERT(pages_lock_->IsOwnedByCurrentThread()); |
238 usage_.capacity_in_words += increase_in_words; | 215 usage_.capacity_in_words += increase_in_words; |
239 UpdateMaxCapacityLocked(); | 216 UpdateMaxCapacityLocked(); |
240 } | 217 } |
241 | 218 |
242 void UpdateMaxCapacityLocked(); | 219 void UpdateMaxCapacityLocked(); |
243 void UpdateMaxUsed(); | 220 void UpdateMaxUsed(); |
244 | 221 |
245 int64_t ExternalInWords() const { | 222 int64_t ExternalInWords() const { return usage_.external_in_words; } |
246 return usage_.external_in_words; | |
247 } | |
248 SpaceUsage GetCurrentUsage() const { | 223 SpaceUsage GetCurrentUsage() const { |
249 MutexLocker ml(pages_lock_); | 224 MutexLocker ml(pages_lock_); |
250 return usage_; | 225 return usage_; |
251 } | 226 } |
252 | 227 |
253 bool Contains(uword addr) const; | 228 bool Contains(uword addr) const; |
254 bool Contains(uword addr, HeapPage::PageType type) const; | 229 bool Contains(uword addr, HeapPage::PageType type) const; |
255 bool IsValidAddress(uword addr) const { | 230 bool IsValidAddress(uword addr) const { return Contains(addr); } |
256 return Contains(addr); | |
257 } | |
258 | 231 |
259 void VisitObjects(ObjectVisitor* visitor) const; | 232 void VisitObjects(ObjectVisitor* visitor) const; |
260 void VisitObjectsNoEmbedderPages(ObjectVisitor* visitor) const; | 233 void VisitObjectsNoEmbedderPages(ObjectVisitor* visitor) const; |
261 void VisitObjectPointers(ObjectPointerVisitor* visitor) const; | 234 void VisitObjectPointers(ObjectPointerVisitor* visitor) const; |
262 | 235 |
263 RawObject* FindObject(FindObjectVisitor* visitor, | 236 RawObject* FindObject(FindObjectVisitor* visitor, |
264 HeapPage::PageType type) const; | 237 HeapPage::PageType type) const; |
265 | 238 |
266 // Checks if enough time has elapsed since the last attempt to collect | 239 // Checks if enough time has elapsed since the last attempt to collect |
267 // code. | 240 // code. |
(...skipping 10 matching lines...) Expand all Loading... |
278 } | 251 } |
279 | 252 |
280 void SetGrowthControlState(bool state) { | 253 void SetGrowthControlState(bool state) { |
281 if (state) { | 254 if (state) { |
282 page_space_controller_.Enable(); | 255 page_space_controller_.Enable(); |
283 } else { | 256 } else { |
284 page_space_controller_.Disable(); | 257 page_space_controller_.Disable(); |
285 } | 258 } |
286 } | 259 } |
287 | 260 |
288 bool GrowthControlState() { | 261 bool GrowthControlState() { return page_space_controller_.is_enabled(); } |
289 return page_space_controller_.is_enabled(); | |
290 } | |
291 | 262 |
292 bool NeedsExternalGC() const { | 263 bool NeedsExternalGC() const { |
293 return (max_external_in_words_ != 0) && | 264 return (max_external_in_words_ != 0) && |
294 (ExternalInWords() > max_external_in_words_); | 265 (ExternalInWords() > max_external_in_words_); |
295 } | 266 } |
296 | 267 |
297 // Note: Code pages are made executable/non-executable when 'read_only' is | 268 // Note: Code pages are made executable/non-executable when 'read_only' is |
298 // true/false, respectively. | 269 // true/false, respectively. |
299 void WriteProtect(bool read_only); | 270 void WriteProtect(bool read_only); |
300 void WriteProtectCode(bool read_only); | 271 void WriteProtectCode(bool read_only); |
301 | 272 |
302 void AddGCTime(int64_t micros) { | 273 void AddGCTime(int64_t micros) { gc_time_micros_ += micros; } |
303 gc_time_micros_ += micros; | |
304 } | |
305 | 274 |
306 int64_t gc_time_micros() const { | 275 int64_t gc_time_micros() const { return gc_time_micros_; } |
307 return gc_time_micros_; | |
308 } | |
309 | 276 |
310 void IncrementCollections() { | 277 void IncrementCollections() { collections_++; } |
311 collections_++; | |
312 } | |
313 | 278 |
314 intptr_t collections() const { | 279 intptr_t collections() const { return collections_; } |
315 return collections_; | |
316 } | |
317 | 280 |
318 #ifndef PRODUCT | 281 #ifndef PRODUCT |
319 void PrintToJSONObject(JSONObject* object) const; | 282 void PrintToJSONObject(JSONObject* object) const; |
320 void PrintHeapMapToJSONStream(Isolate* isolate, JSONStream* stream) const; | 283 void PrintHeapMapToJSONStream(Isolate* isolate, JSONStream* stream) const; |
321 #endif // PRODUCT | 284 #endif // PRODUCT |
322 | 285 |
323 void AllocateExternal(intptr_t size); | 286 void AllocateExternal(intptr_t size); |
324 void FreeExternal(intptr_t size); | 287 void FreeExternal(intptr_t size); |
325 | 288 |
326 // Bulk data allocation. | 289 // Bulk data allocation. |
327 void AcquireDataLock(); | 290 void AcquireDataLock(); |
328 void ReleaseDataLock(); | 291 void ReleaseDataLock(); |
329 | 292 |
330 uword TryAllocateDataLocked(intptr_t size, GrowthPolicy growth_policy) { | 293 uword TryAllocateDataLocked(intptr_t size, GrowthPolicy growth_policy) { |
331 bool is_protected = false; | 294 bool is_protected = false; |
332 bool is_locked = true; | 295 bool is_locked = true; |
333 return TryAllocateInternal(size, | 296 return TryAllocateInternal(size, HeapPage::kData, growth_policy, |
334 HeapPage::kData, | |
335 growth_policy, | |
336 is_protected, is_locked); | 297 is_protected, is_locked); |
337 } | 298 } |
338 | 299 |
339 Monitor* tasks_lock() const { return tasks_lock_; } | 300 Monitor* tasks_lock() const { return tasks_lock_; } |
340 intptr_t tasks() const { return tasks_; } | 301 intptr_t tasks() const { return tasks_; } |
341 void set_tasks(intptr_t val) { | 302 void set_tasks(intptr_t val) { |
342 ASSERT(val >= 0); | 303 ASSERT(val >= 0); |
343 tasks_ = val; | 304 tasks_ = val; |
344 } | 305 } |
345 | 306 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 friend class HeapIterationScope; | 423 friend class HeapIterationScope; |
463 friend class PageSpaceController; | 424 friend class PageSpaceController; |
464 friend class SweeperTask; | 425 friend class SweeperTask; |
465 | 426 |
466 DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpace); | 427 DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpace); |
467 }; | 428 }; |
468 | 429 |
469 } // namespace dart | 430 } // namespace dart |
470 | 431 |
471 #endif // RUNTIME_VM_PAGES_H_ | 432 #endif // RUNTIME_VM_PAGES_H_ |
OLD | NEW |