| 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_SCAVENGER_H_ | 5 #ifndef RUNTIME_VM_SCAVENGER_H_ |
| 6 #define RUNTIME_VM_SCAVENGER_H_ | 6 #define RUNTIME_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" |
| 11 #include "vm/flags.h" | 11 #include "vm/flags.h" |
| 12 #include "vm/globals.h" | 12 #include "vm/globals.h" |
| 13 #include "vm/lockers.h" | |
| 14 #include "vm/raw_object.h" | 13 #include "vm/raw_object.h" |
| 15 #include "vm/ring_buffer.h" | 14 #include "vm/ring_buffer.h" |
| 16 #include "vm/spaces.h" | 15 #include "vm/spaces.h" |
| 17 #include "vm/virtual_memory.h" | 16 #include "vm/virtual_memory.h" |
| 18 #include "vm/visitor.h" | 17 #include "vm/visitor.h" |
| 19 | 18 |
| 20 namespace dart { | 19 namespace dart { |
| 21 | 20 |
| 22 // Forward declarations. | 21 // Forward declarations. |
| 23 class Heap; | 22 class Heap; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 ~Scavenger(); | 116 ~Scavenger(); |
| 118 | 117 |
| 119 // Check whether this Scavenger contains this address. | 118 // Check whether this Scavenger contains this address. |
| 120 // During scavenging both the to and from spaces contain "legal" objects. | 119 // During scavenging both the to and from spaces contain "legal" objects. |
| 121 // During a scavenge this function only returns true for addresses that will | 120 // During a scavenge this function only returns true for addresses that will |
| 122 // be part of the surviving objects. | 121 // be part of the surviving objects. |
| 123 bool Contains(uword addr) const { return to_->Contains(addr); } | 122 bool Contains(uword addr) const { return to_->Contains(addr); } |
| 124 | 123 |
| 125 RawObject* FindObject(FindObjectVisitor* visitor) const; | 124 RawObject* FindObject(FindObjectVisitor* visitor) const; |
| 126 | 125 |
| 127 uword TryAllocateNewTLAB(Thread* thread, intptr_t size) { | |
| 128 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | |
| 129 ASSERT(heap_ != Dart::vm_isolate()->heap()); | |
| 130 ASSERT(!scavenging_); | |
| 131 MutexLocker ml(space_lock_); | |
| 132 uword result = top_; | |
| 133 intptr_t remaining = end_ - top_; | |
| 134 if (remaining < size) { | |
| 135 return 0; | |
| 136 } | |
| 137 ASSERT(to_->Contains(result)); | |
| 138 ASSERT((result & kObjectAlignmentMask) == object_alignment_); | |
| 139 top_ += size; | |
| 140 ASSERT(to_->Contains(top_) || (top_ == to_->end())); | |
| 141 ASSERT(result < top_); | |
| 142 thread->set_top(result); | |
| 143 thread->set_end(top_); | |
| 144 return result; | |
| 145 } | |
| 146 | |
| 147 uword AllocateGC(intptr_t size) { | 126 uword AllocateGC(intptr_t size) { |
| 148 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 127 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 149 ASSERT(heap_ != Dart::vm_isolate()->heap()); | 128 ASSERT(heap_ != Dart::vm_isolate()->heap()); |
| 150 ASSERT(scavenging_); | 129 ASSERT(scavenging_); |
| 151 uword result = top_; | 130 uword result = top_; |
| 152 intptr_t remaining = end_ - top_; | 131 intptr_t remaining = end_ - top_; |
| 153 | 132 |
| 154 // This allocation happens only in GC and only when copying objects to | 133 // This allocation happens only in GC and only when copying objects to |
| 155 // the new to_ space. It must succeed. | 134 // the new to_ space. It must succeed. |
| 156 ASSERT(size <= remaining); | 135 ASSERT(size <= remaining); |
| 157 ASSERT(to_->Contains(result)); | 136 ASSERT(to_->Contains(result)); |
| 158 ASSERT((result & kObjectAlignmentMask) == object_alignment_); | 137 ASSERT((result & kObjectAlignmentMask) == object_alignment_); |
| 159 top_ += size; | 138 top_ += size; |
| 160 ASSERT((to_->Contains(top_)) || (top_ == to_->end())); | 139 ASSERT(to_->Contains(top_) || (top_ == to_->end())); |
| 161 return result; | 140 return result; |
| 162 } | 141 } |
| 163 | 142 |
| 164 uword TryAllocateInTLAB(Thread* thread, intptr_t size) { | 143 uword TryAllocateInTLAB(Thread* thread, intptr_t size) { |
| 165 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 144 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 166 ASSERT(heap_ != Dart::vm_isolate()->heap()); | 145 ASSERT(heap_ != Dart::vm_isolate()->heap()); |
| 167 ASSERT(thread->IsMutatorThread()); | 146 ASSERT(thread->IsMutatorThread()); |
| 168 ASSERT(thread->isolate()->IsMutatorThreadScheduled()); | 147 ASSERT(thread->isolate()->IsMutatorThreadScheduled()); |
| 169 ASSERT(thread->top() <= top_); | |
| 170 ASSERT((thread->end() == 0) || (thread->end() == top_)); | |
| 171 #if defined(DEBUG) | 148 #if defined(DEBUG) |
| 172 if (FLAG_gc_at_alloc) { | 149 if (FLAG_gc_at_alloc) { |
| 173 ASSERT(!scavenging_); | 150 ASSERT(!scavenging_); |
| 174 Scavenge(); | 151 Scavenge(); |
| 175 } | 152 } |
| 176 #endif | 153 #endif |
| 177 uword top = thread->top(); | 154 uword top = thread->top(); |
| 178 uword end = thread->end(); | 155 uword end = thread->end(); |
| 179 uword result = top; | 156 uword result = top; |
| 180 intptr_t remaining = end - top; | 157 intptr_t remaining = end - top; |
| 181 if (remaining < size) { | 158 if (remaining < size) { |
| 182 return 0; | 159 return 0; |
| 183 } | 160 } |
| 184 ASSERT(to_->Contains(result)); | 161 ASSERT(to_->Contains(result)); |
| 185 ASSERT((result & kObjectAlignmentMask) == object_alignment_); | 162 ASSERT((result & kObjectAlignmentMask) == object_alignment_); |
| 186 top += size; | 163 top += size; |
| 187 ASSERT((to_->Contains(top)) || (top == to_->end())); | 164 ASSERT(to_->Contains(top) || (top == to_->end())); |
| 188 thread->set_top(top); | 165 thread->set_top(top); |
| 189 return result; | 166 return result; |
| 190 } | 167 } |
| 191 | 168 |
| 192 // Collect the garbage in this scavenger. | 169 // Collect the garbage in this scavenger. |
| 193 void Scavenge(); | 170 void Scavenge(); |
| 194 | 171 |
| 195 // Promote all live objects. | 172 // Promote all live objects. |
| 196 void Evacuate(); | 173 void Evacuate(); |
| 197 | 174 |
| 198 uword top() { return top_; } | 175 uword top() { return top_; } |
| 199 uword end() { return end_; } | 176 uword end() { return end_; } |
| 200 | 177 |
| 201 void set_top(uword value) { top_ = value; } | 178 void set_top(uword value) { top_ = value; } |
| 202 void set_end(uword value) { | 179 void set_end(uword value) { |
| 203 ASSERT(to_->end() == value); | 180 ASSERT(to_->end() == value); |
| 204 end_ = value; | 181 end_ = value; |
| 205 } | 182 } |
| 206 | 183 |
| 207 int64_t UsedInWords() const; | 184 int64_t UsedInWords() const { |
| 185 return (top_ - FirstObjectStart()) >> kWordSizeLog2; |
| 186 } |
| 208 int64_t CapacityInWords() const { return to_->size_in_words(); } | 187 int64_t CapacityInWords() const { return to_->size_in_words(); } |
| 209 int64_t ExternalInWords() const { return external_size_ >> kWordSizeLog2; } | 188 int64_t ExternalInWords() const { return external_size_ >> kWordSizeLog2; } |
| 210 SpaceUsage GetCurrentUsage() const { | 189 SpaceUsage GetCurrentUsage() const { |
| 211 SpaceUsage usage; | 190 SpaceUsage usage; |
| 212 usage.used_in_words = UsedInWords(); | 191 usage.used_in_words = UsedInWords(); |
| 213 usage.capacity_in_words = CapacityInWords(); | 192 usage.capacity_in_words = CapacityInWords(); |
| 214 usage.external_in_words = ExternalInWords(); | 193 usage.external_in_words = ExternalInWords(); |
| 215 return usage; | 194 return usage; |
| 216 } | 195 } |
| 217 | 196 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 230 | 209 |
| 231 intptr_t collections() const { return collections_; } | 210 intptr_t collections() const { return collections_; } |
| 232 | 211 |
| 233 #ifndef PRODUCT | 212 #ifndef PRODUCT |
| 234 void PrintToJSONObject(JSONObject* object) const; | 213 void PrintToJSONObject(JSONObject* object) const; |
| 235 #endif // !PRODUCT | 214 #endif // !PRODUCT |
| 236 | 215 |
| 237 void AllocateExternal(intptr_t size); | 216 void AllocateExternal(intptr_t size); |
| 238 void FreeExternal(intptr_t size); | 217 void FreeExternal(intptr_t size); |
| 239 | 218 |
| 240 void MakeNewSpaceIterable() const; | 219 void FlushTLS() const; |
| 241 int64_t FreeSpaceInWords(Isolate* isolate) const; | |
| 242 void MakeAllTLABsIterable(Isolate* isolate) const; | |
| 243 void AbandonAllTLABs(Isolate* isolate); | |
| 244 | 220 |
| 245 private: | 221 private: |
| 246 // Ids for time and data records in Heap::GCStats. | 222 // Ids for time and data records in Heap::GCStats. |
| 247 enum { | 223 enum { |
| 248 // Time | 224 // Time |
| 249 kDummyScavengeTime = 0, | 225 kDummyScavengeTime = 0, |
| 250 kSafePoint = 1, | 226 kSafePoint = 1, |
| 251 kVisitIsolateRoots = 2, | 227 kVisitIsolateRoots = 2, |
| 252 kIterateStoreBuffers = 3, | 228 kIterateStoreBuffers = 3, |
| 253 kProcessToSpace = 4, | 229 kProcessToSpace = 4, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 int64_t gc_time_micros_; | 308 int64_t gc_time_micros_; |
| 333 intptr_t collections_; | 309 intptr_t collections_; |
| 334 static const int kStatsHistoryCapacity = 2; | 310 static const int kStatsHistoryCapacity = 2; |
| 335 RingBuffer<ScavengeStats, kStatsHistoryCapacity> stats_history_; | 311 RingBuffer<ScavengeStats, kStatsHistoryCapacity> stats_history_; |
| 336 | 312 |
| 337 // The total size of external data associated with objects in this scavenger. | 313 // The total size of external data associated with objects in this scavenger. |
| 338 intptr_t external_size_; | 314 intptr_t external_size_; |
| 339 | 315 |
| 340 bool failed_to_promote_; | 316 bool failed_to_promote_; |
| 341 | 317 |
| 342 // Protects new space during the allocation of new TLABs | |
| 343 Mutex* space_lock_; | |
| 344 friend class ScavengerVisitor; | 318 friend class ScavengerVisitor; |
| 345 friend class ScavengerWeakVisitor; | 319 friend class ScavengerWeakVisitor; |
| 346 | 320 |
| 347 DISALLOW_COPY_AND_ASSIGN(Scavenger); | 321 DISALLOW_COPY_AND_ASSIGN(Scavenger); |
| 348 }; | 322 }; |
| 349 | 323 |
| 350 } // namespace dart | 324 } // namespace dart |
| 351 | 325 |
| 352 #endif // RUNTIME_VM_SCAVENGER_H_ | 326 #endif // RUNTIME_VM_SCAVENGER_H_ |
| OLD | NEW |