| 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 |