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 VM_PAGES_H_ | 5 #ifndef VM_PAGES_H_ |
6 #define VM_PAGES_H_ | 6 #define 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/spaces.h" | |
11 #include "vm/virtual_memory.h" | 10 #include "vm/virtual_memory.h" |
12 | 11 |
13 namespace dart { | 12 namespace dart { |
14 | 13 |
15 DECLARE_FLAG(bool, collect_code); | 14 DECLARE_FLAG(bool, collect_code); |
16 DECLARE_FLAG(bool, log_code_drop); | 15 DECLARE_FLAG(bool, log_code_drop); |
17 DECLARE_FLAG(bool, always_drop_code); | 16 DECLARE_FLAG(bool, always_drop_code); |
18 | 17 |
19 // Forward declarations. | 18 // Forward declarations. |
20 class Heap; | 19 class Heap; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 // and if the relative GC time is below a given threshold, | 109 // and if the relative GC time is below a given threshold, |
111 // then the heap is not grown when the next GC decision is made. | 110 // then the heap is not grown when the next GC decision is made. |
112 // PageSpaceController controls the heap size. | 111 // PageSpaceController controls the heap size. |
113 class PageSpaceController { | 112 class PageSpaceController { |
114 public: | 113 public: |
115 PageSpaceController(int heap_growth_ratio, | 114 PageSpaceController(int heap_growth_ratio, |
116 int heap_growth_rate, | 115 int heap_growth_rate, |
117 int garbage_collection_time_ratio); | 116 int garbage_collection_time_ratio); |
118 ~PageSpaceController(); | 117 ~PageSpaceController(); |
119 | 118 |
120 // Returns whether growing to 'after' should trigger a GC. | 119 bool CanGrowPageSpace(intptr_t size_in_bytes); |
121 // This method can be called before allocation (e.g., pretenuring) or after | |
122 // (e.g., promotion), as it does not change the state of the controller. | |
123 bool NeedsGarbageCollection(SpaceUsage after) const; | |
124 | 120 |
125 // Should be called after each collection to update the controller state. | |
126 // A garbage collection is considered as successful if more than | 121 // A garbage collection is considered as successful if more than |
127 // heap_growth_ratio % of memory got deallocated by the garbage collector. | 122 // heap_growth_ratio % of memory got deallocated by the garbage collector. |
128 // In this case garbage collection will be performed next time. Otherwise | 123 // In this case garbage collection will be performed next time. Otherwise |
129 // the heap will grow. | 124 // the heap will grow. |
130 void EvaluateGarbageCollection(SpaceUsage before, | 125 void EvaluateGarbageCollection(intptr_t used_before_in_words, |
131 SpaceUsage after, | 126 intptr_t used_after_in_words, |
132 int64_t start, int64_t end); | 127 int64_t start, int64_t end); |
133 | 128 |
134 int64_t last_code_collection_in_us() { return last_code_collection_in_us_; } | 129 int64_t last_code_collection_in_us() { return last_code_collection_in_us_; } |
135 void set_last_code_collection_in_us(int64_t t) { | 130 void set_last_code_collection_in_us(int64_t t) { |
136 last_code_collection_in_us_ = t; | 131 last_code_collection_in_us_ = t; |
137 } | 132 } |
138 | 133 |
139 void set_is_enabled(bool state) { | 134 void set_is_enabled(bool state) { |
140 is_enabled_ = state; | 135 is_enabled_ = state; |
141 } | 136 } |
142 bool is_enabled() { | 137 bool is_enabled() { |
143 return is_enabled_; | 138 return is_enabled_; |
144 } | 139 } |
145 | 140 |
146 private: | 141 private: |
147 bool is_enabled_; | 142 bool is_enabled_; |
148 | 143 |
149 // Usage after last evaluated GC. | |
150 SpaceUsage last_usage_; | |
151 | |
152 // Heap growth control variable. | 144 // Heap growth control variable. |
153 intptr_t grow_heap_; | 145 intptr_t grow_heap_; |
154 | 146 |
155 // If the garbage collector was not able to free more than heap_growth_ratio_ | 147 // If the garbage collector was not able to free more than heap_growth_ratio_ |
156 // memory, then the heap is grown. Otherwise garbage collection is performed. | 148 // memory, then the heap is grown. Otherwise garbage collection is performed. |
157 int heap_growth_ratio_; | 149 int heap_growth_ratio_; |
158 | 150 |
159 // The desired percent of heap in-use after a garbage collection. | 151 // The desired percent of heap in-use after a garbage collection. |
160 // Equivalent to \frac{100-heap_growth_ratio_}{100}. | 152 // Equivalent to \frac{100-heap_growth_ratio_}{100}. |
161 double desired_utilization_; | 153 double desired_utilization_; |
(...skipping 25 matching lines...) Expand all Loading... |
187 kForceGrowth | 179 kForceGrowth |
188 }; | 180 }; |
189 | 181 |
190 PageSpace(Heap* heap, intptr_t max_capacity_in_words); | 182 PageSpace(Heap* heap, intptr_t max_capacity_in_words); |
191 ~PageSpace(); | 183 ~PageSpace(); |
192 | 184 |
193 uword TryAllocate(intptr_t size, | 185 uword TryAllocate(intptr_t size, |
194 HeapPage::PageType type = HeapPage::kData, | 186 HeapPage::PageType type = HeapPage::kData, |
195 GrowthPolicy growth_policy = kControlGrowth); | 187 GrowthPolicy growth_policy = kControlGrowth); |
196 | 188 |
197 bool NeedsGarbageCollection() const { | 189 intptr_t UsedInWords() const { return used_in_words_; } |
198 return page_space_controller_.NeedsGarbageCollection(usage_); | 190 intptr_t CapacityInWords() const { return capacity_in_words_; } |
| 191 intptr_t ExternalInWords() const { |
| 192 return external_in_words_; |
199 } | 193 } |
200 | 194 |
201 intptr_t UsedInWords() const { return usage_.used_in_words; } | |
202 intptr_t CapacityInWords() const { return usage_.capacity_in_words; } | |
203 intptr_t ExternalInWords() const { | |
204 return usage_.external_in_words; | |
205 } | |
206 SpaceUsage GetCurrentUsage() const { return usage_; } | |
207 | |
208 bool Contains(uword addr) const; | 195 bool Contains(uword addr) const; |
209 bool Contains(uword addr, HeapPage::PageType type) const; | 196 bool Contains(uword addr, HeapPage::PageType type) const; |
210 bool IsValidAddress(uword addr) const { | 197 bool IsValidAddress(uword addr) const { |
211 return Contains(addr); | 198 return Contains(addr); |
212 } | 199 } |
213 | 200 |
214 void VisitObjects(ObjectVisitor* visitor) const; | 201 void VisitObjects(ObjectVisitor* visitor) const; |
215 void VisitObjectPointers(ObjectPointerVisitor* visitor) const; | 202 void VisitObjectPointers(ObjectPointerVisitor* visitor) const; |
216 | 203 |
217 RawObject* FindObject(FindObjectVisitor* visitor, | 204 RawObject* FindObject(FindObjectVisitor* visitor, |
(...skipping 10 matching lines...) Expand all Loading... |
228 | 215 |
229 void SetGrowthControlState(bool state) { | 216 void SetGrowthControlState(bool state) { |
230 page_space_controller_.set_is_enabled(state); | 217 page_space_controller_.set_is_enabled(state); |
231 } | 218 } |
232 | 219 |
233 bool GrowthControlState() { | 220 bool GrowthControlState() { |
234 return page_space_controller_.is_enabled(); | 221 return page_space_controller_.is_enabled(); |
235 } | 222 } |
236 | 223 |
237 bool NeedExternalGC() { | 224 bool NeedExternalGC() { |
238 return UsedInWords() + ExternalInWords() > max_capacity_in_words_; | 225 return used_in_words_ + ExternalInWords() > max_capacity_in_words_; |
239 } | 226 } |
240 | 227 |
241 void WriteProtect(bool read_only); | 228 void WriteProtect(bool read_only); |
242 | 229 |
243 void AddGCTime(int64_t micros) { | 230 void AddGCTime(int64_t micros) { |
244 gc_time_micros_ += micros; | 231 gc_time_micros_ += micros; |
245 } | 232 } |
246 | 233 |
247 int64_t gc_time_micros() const { | 234 int64_t gc_time_micros() const { |
248 return gc_time_micros_; | 235 return gc_time_micros_; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 | 268 |
282 HeapPage* AllocatePage(HeapPage::PageType type); | 269 HeapPage* AllocatePage(HeapPage::PageType type); |
283 void FreePage(HeapPage* page, HeapPage* previous_page); | 270 void FreePage(HeapPage* page, HeapPage* previous_page); |
284 HeapPage* AllocateLargePage(intptr_t size, HeapPage::PageType type); | 271 HeapPage* AllocateLargePage(intptr_t size, HeapPage::PageType type); |
285 void FreeLargePage(HeapPage* page, HeapPage* previous_page); | 272 void FreeLargePage(HeapPage* page, HeapPage* previous_page); |
286 void FreePages(HeapPage* pages); | 273 void FreePages(HeapPage* pages); |
287 | 274 |
288 static intptr_t LargePageSizeInWordsFor(intptr_t size); | 275 static intptr_t LargePageSizeInWordsFor(intptr_t size); |
289 | 276 |
290 bool CanIncreaseCapacityInWords(intptr_t increase_in_words) { | 277 bool CanIncreaseCapacityInWords(intptr_t increase_in_words) { |
291 ASSERT(CapacityInWords() <= max_capacity_in_words_); | 278 ASSERT(capacity_in_words_ <= max_capacity_in_words_); |
292 return increase_in_words <= (max_capacity_in_words_ - CapacityInWords()); | 279 return increase_in_words <= (max_capacity_in_words_ - capacity_in_words_); |
293 } | 280 } |
294 | 281 |
295 FreeList freelist_[HeapPage::kNumPageTypes]; | 282 FreeList freelist_[HeapPage::kNumPageTypes]; |
296 | 283 |
297 Heap* heap_; | 284 Heap* heap_; |
298 | 285 |
299 HeapPage* pages_; | 286 HeapPage* pages_; |
300 HeapPage* pages_tail_; | 287 HeapPage* pages_tail_; |
301 HeapPage* large_pages_; | 288 HeapPage* large_pages_; |
302 | 289 |
303 // Various sizes being tracked for this generation. | 290 // Various sizes being tracked for this generation. |
304 intptr_t max_capacity_in_words_; | 291 intptr_t max_capacity_in_words_; |
305 SpaceUsage usage_; | 292 intptr_t capacity_in_words_; |
| 293 intptr_t used_in_words_; |
| 294 intptr_t external_in_words_; |
306 | 295 |
307 // Keep track whether a MarkSweep is currently running. | 296 // Keep track whether a MarkSweep is currently running. |
308 bool sweeping_; | 297 bool sweeping_; |
309 | 298 |
310 PageSpaceController page_space_controller_; | 299 PageSpaceController page_space_controller_; |
311 | 300 |
312 int64_t gc_time_micros_; | 301 int64_t gc_time_micros_; |
313 intptr_t collections_; | 302 intptr_t collections_; |
314 | 303 |
315 friend class PageSpaceController; | 304 friend class PageSpaceController; |
316 | 305 |
317 DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpace); | 306 DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpace); |
318 }; | 307 }; |
319 | 308 |
320 } // namespace dart | 309 } // namespace dart |
321 | 310 |
322 #endif // VM_PAGES_H_ | 311 #endif // VM_PAGES_H_ |
OLD | NEW |