| 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 VM_SCAVENGER_H_ | 5 #ifndef VM_SCAVENGER_H_ |
| 6 #define VM_SCAVENGER_H_ | 6 #define VM_SCAVENGER_H_ |
| 7 | 7 |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "platform/utils.h" | 9 #include "platform/utils.h" |
| 10 #include "vm/dart.h" | 10 #include "vm/dart.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 DECLARE_FLAG(bool, gc_at_alloc); | 27 DECLARE_FLAG(bool, gc_at_alloc); |
| 28 | 28 |
| 29 | 29 |
| 30 // Wrapper around VirtualMemory that adds caching and handles the empty case. | 30 // Wrapper around VirtualMemory that adds caching and handles the empty case. |
| 31 class SemiSpace { | 31 class SemiSpace { |
| 32 public: | 32 public: |
| 33 static void InitOnce(); | 33 static void InitOnce(); |
| 34 | 34 |
| 35 // Get a space of the given size. Returns NULL on out of memory. If size is 0, | 35 // Get a space of the given size. Returns NULL on out of memory. If size is 0, |
| 36 // returns an empty space: pointer(), start() and end() all return NULL. | 36 // returns an empty space: pointer(), start() and end() all return NULL. |
| 37 static SemiSpace* New(intptr_t size); | 37 static SemiSpace* New(intptr_t size_in_words); |
| 38 | 38 |
| 39 // Hand back an unused space. | 39 // Hand back an unused space. |
| 40 void Delete(); | 40 void Delete(); |
| 41 | 41 |
| 42 void* pointer() const { return region_.pointer(); } | 42 void* pointer() const { return region_.pointer(); } |
| 43 uword start() const { return region_.start(); } | 43 uword start() const { return region_.start(); } |
| 44 uword end() const { return region_.end(); } | 44 uword end() const { return region_.end(); } |
| 45 intptr_t size() const { return static_cast<intptr_t>(region_.size()); } | 45 intptr_t size_in_words() const { |
| 46 return static_cast<intptr_t>(region_.size()) >> kWordSizeLog2; |
| 47 } |
| 46 bool Contains(uword address) const { return region_.Contains(address); } | 48 bool Contains(uword address) const { return region_.Contains(address); } |
| 47 | 49 |
| 48 // Set write protection mode for this space. The space must not be protected | 50 // Set write protection mode for this space. The space must not be protected |
| 49 // when Delete is called. | 51 // when Delete is called. |
| 50 // TODO(koda): Remember protection mode in VirtualMemory and assert this. | 52 // TODO(koda): Remember protection mode in VirtualMemory and assert this. |
| 51 void WriteProtect(bool read_only); | 53 void WriteProtect(bool read_only); |
| 52 | 54 |
| 53 private: | 55 private: |
| 54 explicit SemiSpace(VirtualMemory* reserved); | 56 explicit SemiSpace(VirtualMemory* reserved); |
| 55 ~SemiSpace(); | 57 ~SemiSpace(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 int64_t end_micros_; | 104 int64_t end_micros_; |
| 103 SpaceUsage before_; | 105 SpaceUsage before_; |
| 104 SpaceUsage after_; | 106 SpaceUsage after_; |
| 105 intptr_t promo_candidates_in_words_; | 107 intptr_t promo_candidates_in_words_; |
| 106 intptr_t promoted_in_words_; | 108 intptr_t promoted_in_words_; |
| 107 }; | 109 }; |
| 108 | 110 |
| 109 | 111 |
| 110 class Scavenger { | 112 class Scavenger { |
| 111 public: | 113 public: |
| 112 Scavenger(Heap* heap, intptr_t max_capacity_in_words, uword object_alignment); | 114 Scavenger(Heap* heap, |
| 115 intptr_t max_semi_capacity_in_words, |
| 116 uword object_alignment); |
| 113 ~Scavenger(); | 117 ~Scavenger(); |
| 114 | 118 |
| 115 // Check whether this Scavenger contains this address. | 119 // Check whether this Scavenger contains this address. |
| 116 // During scavenging both the to and from spaces contain "legal" objects. | 120 // During scavenging both the to and from spaces contain "legal" objects. |
| 117 // During a scavenge this function only returns true for addresses that will | 121 // During a scavenge this function only returns true for addresses that will |
| 118 // be part of the surviving objects. | 122 // be part of the surviving objects. |
| 119 bool Contains(uword addr) const { | 123 bool Contains(uword addr) const { |
| 120 // No reasonable algorithm should be checking for objects in from space. At | 124 // No reasonable algorithm should be checking for objects in from space. At |
| 121 // least unless it is debugging code. This might need to be relaxed later, | 125 // least unless it is debugging code. This might need to be relaxed later, |
| 122 // but currently it helps prevent dumb bugs. | 126 // but currently it helps prevent dumb bugs. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 // Accessors to generate code for inlined allocation. | 158 // Accessors to generate code for inlined allocation. |
| 155 uword* TopAddress() { return &top_; } | 159 uword* TopAddress() { return &top_; } |
| 156 uword* EndAddress() { return &end_; } | 160 uword* EndAddress() { return &end_; } |
| 157 static intptr_t top_offset() { return OFFSET_OF(Scavenger, top_); } | 161 static intptr_t top_offset() { return OFFSET_OF(Scavenger, top_); } |
| 158 static intptr_t end_offset() { return OFFSET_OF(Scavenger, end_); } | 162 static intptr_t end_offset() { return OFFSET_OF(Scavenger, end_); } |
| 159 | 163 |
| 160 intptr_t UsedInWords() const { | 164 intptr_t UsedInWords() const { |
| 161 return (top_ - FirstObjectStart()) >> kWordSizeLog2; | 165 return (top_ - FirstObjectStart()) >> kWordSizeLog2; |
| 162 } | 166 } |
| 163 intptr_t CapacityInWords() const { | 167 intptr_t CapacityInWords() const { |
| 164 return to_->size() >> kWordSizeLog2; | 168 return to_->size_in_words(); |
| 165 } | 169 } |
| 166 intptr_t ExternalInWords() const { | 170 intptr_t ExternalInWords() const { |
| 167 return external_size_ >> kWordSizeLog2; | 171 return external_size_ >> kWordSizeLog2; |
| 168 } | 172 } |
| 169 SpaceUsage GetCurrentUsage() const { | 173 SpaceUsage GetCurrentUsage() const { |
| 170 SpaceUsage usage; | 174 SpaceUsage usage; |
| 171 usage.used_in_words = UsedInWords(); | 175 usage.used_in_words = UsedInWords(); |
| 172 usage.capacity_in_words = CapacityInWords(); | 176 usage.capacity_in_words = CapacityInWords(); |
| 173 usage.external_in_words = ExternalInWords(); | 177 usage.external_in_words = ExternalInWords(); |
| 174 return usage; | 178 return usage; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 ASSERT(end_ <= to_->end()); | 262 ASSERT(end_ <= to_->end()); |
| 259 return result; | 263 return result; |
| 260 } | 264 } |
| 261 bool PromotedStackHasMore() const { | 265 bool PromotedStackHasMore() const { |
| 262 ASSERT(scavenging_); | 266 ASSERT(scavenging_); |
| 263 return end_ < to_->end(); | 267 return end_ < to_->end(); |
| 264 } | 268 } |
| 265 | 269 |
| 266 void ProcessWeakTables(); | 270 void ProcessWeakTables(); |
| 267 | 271 |
| 272 intptr_t NewSizeInWords(intptr_t old_size_in_words) const; |
| 273 |
| 268 SemiSpace* from_; | 274 SemiSpace* from_; |
| 269 SemiSpace* to_; | 275 SemiSpace* to_; |
| 270 | 276 |
| 271 Heap* heap_; | 277 Heap* heap_; |
| 272 | 278 |
| 273 // Current allocation top and end. These values are being accessed directly | 279 // Current allocation top and end. These values are being accessed directly |
| 274 // from generated code. | 280 // from generated code. |
| 275 uword top_; | 281 uword top_; |
| 276 uword end_; | 282 uword end_; |
| 277 | 283 |
| 278 // A pointer to the first unscanned object. Scanning completes when | 284 // A pointer to the first unscanned object. Scanning completes when |
| 279 // this value meets the allocation top. | 285 // this value meets the allocation top. |
| 280 uword resolved_top_; | 286 uword resolved_top_; |
| 281 | 287 |
| 282 // Objects below this address have survived a scavenge. | 288 // Objects below this address have survived a scavenge. |
| 283 uword survivor_end_; | 289 uword survivor_end_; |
| 284 | 290 |
| 291 intptr_t max_semi_capacity_in_words_; |
| 292 |
| 285 // All object are aligned to this value. | 293 // All object are aligned to this value. |
| 286 uword object_alignment_; | 294 uword object_alignment_; |
| 287 | 295 |
| 288 // Keep track whether a scavenge is currently running. | 296 // Keep track whether a scavenge is currently running. |
| 289 bool scavenging_; | 297 bool scavenging_; |
| 290 | 298 |
| 291 int64_t gc_time_micros_; | 299 int64_t gc_time_micros_; |
| 292 intptr_t collections_; | 300 intptr_t collections_; |
| 293 static const int kStatsHistoryCapacity = 2; | 301 static const int kStatsHistoryCapacity = 2; |
| 294 RingBuffer<ScavengeStats, kStatsHistoryCapacity> stats_history_; | 302 RingBuffer<ScavengeStats, kStatsHistoryCapacity> stats_history_; |
| 295 | 303 |
| 296 // The total size of external data associated with objects in this scavenger. | 304 // The total size of external data associated with objects in this scavenger. |
| 297 intptr_t external_size_; | 305 intptr_t external_size_; |
| 298 | 306 |
| 299 friend class ScavengerVisitor; | 307 friend class ScavengerVisitor; |
| 300 friend class ScavengerWeakVisitor; | 308 friend class ScavengerWeakVisitor; |
| 301 | 309 |
| 302 DISALLOW_COPY_AND_ASSIGN(Scavenger); | 310 DISALLOW_COPY_AND_ASSIGN(Scavenger); |
| 303 }; | 311 }; |
| 304 | 312 |
| 305 } // namespace dart | 313 } // namespace dart |
| 306 | 314 |
| 307 #endif // VM_SCAVENGER_H_ | 315 #endif // VM_SCAVENGER_H_ |
| OLD | NEW |