| 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" |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 ~Scavenger(); | 114 ~Scavenger(); |
| 115 | 115 |
| 116 // Check whether this Scavenger contains this address. | 116 // Check whether this Scavenger contains this address. |
| 117 // During scavenging both the to and from spaces contain "legal" objects. | 117 // During scavenging both the to and from spaces contain "legal" objects. |
| 118 // During a scavenge this function only returns true for addresses that will | 118 // During a scavenge this function only returns true for addresses that will |
| 119 // be part of the surviving objects. | 119 // be part of the surviving objects. |
| 120 bool Contains(uword addr) const { return to_->Contains(addr); } | 120 bool Contains(uword addr) const { return to_->Contains(addr); } |
| 121 | 121 |
| 122 RawObject* FindObject(FindObjectVisitor* visitor) const; | 122 RawObject* FindObject(FindObjectVisitor* visitor) const; |
| 123 | 123 |
| 124 uword TryAllocateNewTLAB(Thread* thread, intptr_t size) { |
| 125 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 126 ASSERT(heap_ != Dart::vm_isolate()->heap()); |
| 127 ASSERT(!scavenging_); |
| 128 uword result = top_; |
| 129 intptr_t remaining = end_ - top_; |
| 130 if (remaining < size) { |
| 131 return 0; |
| 132 } |
| 133 ASSERT(to_->Contains(result)); |
| 134 ASSERT((result & kObjectAlignmentMask) == object_alignment_); |
| 135 top_ += size; |
| 136 ASSERT(to_->Contains(top_) || (top_ == to_->end())); |
| 137 ASSERT(result < top_); |
| 138 thread->set_top(result); |
| 139 thread->set_end(top_); |
| 140 return result; |
| 141 } |
| 142 |
| 124 uword AllocateGC(intptr_t size) { | 143 uword AllocateGC(intptr_t size) { |
| 125 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 144 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 126 ASSERT(heap_ != Dart::vm_isolate()->heap()); | 145 ASSERT(heap_ != Dart::vm_isolate()->heap()); |
| 127 ASSERT(scavenging_); | 146 ASSERT(scavenging_); |
| 128 uword result = top_; | 147 uword result = top_; |
| 129 intptr_t remaining = end_ - top_; | 148 intptr_t remaining = end_ - top_; |
| 130 | 149 |
| 131 // This allocation happens only in GC and only when copying objects to | 150 // This allocation happens only in GC and only when copying objects to |
| 132 // the new to_ space. It must succeed. | 151 // the new to_ space. It must succeed. |
| 133 ASSERT(size <= remaining); | 152 ASSERT(size <= remaining); |
| 134 ASSERT(to_->Contains(result)); | 153 ASSERT(to_->Contains(result)); |
| 135 ASSERT((result & kObjectAlignmentMask) == object_alignment_); | 154 ASSERT((result & kObjectAlignmentMask) == object_alignment_); |
| 136 top_ += size; | 155 top_ += size; |
| 137 ASSERT(to_->Contains(top_) || (top_ == to_->end())); | 156 ASSERT((to_->Contains(top_)) || (top_ == to_->end())); |
| 138 return result; | 157 return result; |
| 139 } | 158 } |
| 140 | 159 |
| 141 uword TryAllocateInTLAB(Thread* thread, intptr_t size) { | 160 uword TryAllocateInTLAB(Thread* thread, intptr_t size) { |
| 142 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 161 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 143 ASSERT(heap_ != Dart::vm_isolate()->heap()); | 162 ASSERT(heap_ != Dart::vm_isolate()->heap()); |
| 144 ASSERT(thread->IsMutatorThread()); | 163 ASSERT(thread->IsMutatorThread()); |
| 145 ASSERT(thread->isolate()->IsMutatorThreadScheduled()); | 164 ASSERT(thread->isolate()->IsMutatorThreadScheduled()); |
| 165 ASSERT(thread->top() <= top_); |
| 166 ASSERT((thread->end() == 0) || (thread->end() == top_)); |
| 146 #if defined(DEBUG) | 167 #if defined(DEBUG) |
| 147 if (FLAG_gc_at_alloc) { | 168 if (FLAG_gc_at_alloc) { |
| 148 ASSERT(!scavenging_); | 169 ASSERT(!scavenging_); |
| 149 Scavenge(); | 170 Scavenge(); |
| 150 } | 171 } |
| 151 #endif | 172 #endif |
| 152 uword top = thread->top(); | 173 uword top = thread->top(); |
| 153 uword end = thread->end(); | 174 uword end = thread->end(); |
| 154 uword result = top; | 175 uword result = top; |
| 155 intptr_t remaining = end - top; | 176 intptr_t remaining = end - top; |
| 156 if (remaining < size) { | 177 if (remaining < size) { |
| 157 return 0; | 178 return 0; |
| 158 } | 179 } |
| 159 ASSERT(to_->Contains(result)); | 180 ASSERT(to_->Contains(result)); |
| 160 ASSERT((result & kObjectAlignmentMask) == object_alignment_); | 181 ASSERT((result & kObjectAlignmentMask) == object_alignment_); |
| 161 top += size; | 182 top += size; |
| 162 ASSERT(to_->Contains(top) || (top == to_->end())); | 183 ASSERT((to_->Contains(top)) || (top == to_->end())); |
| 163 thread->set_top(top); | 184 thread->set_top(top); |
| 164 return result; | 185 return result; |
| 165 } | 186 } |
| 166 | 187 |
| 167 // Collect the garbage in this scavenger. | 188 // Collect the garbage in this scavenger. |
| 168 void Scavenge(); | 189 void Scavenge(); |
| 169 void Scavenge(bool invoke_api_callbacks); | 190 void Scavenge(bool invoke_api_callbacks); |
| 170 | 191 |
| 171 // Promote all live objects. | 192 // Promote all live objects. |
| 172 void Evacuate(); | 193 void Evacuate(); |
| 173 | 194 |
| 174 uword top() { return top_; } | 195 uword top() { return top_; } |
| 175 uword end() { return end_; } | 196 uword end() { return end_; } |
| 176 | 197 |
| 177 void set_top(uword value) { top_ = value; } | 198 void set_top(uword value) { top_ = value; } |
| 178 void set_end(uword value) { | 199 void set_end(uword value) { |
| 179 ASSERT(to_->end() == value); | 200 ASSERT(to_->end() == value); |
| 180 end_ = value; | 201 end_ = value; |
| 181 } | 202 } |
| 182 | 203 |
| 183 int64_t UsedInWords() const { | 204 int64_t UsedInWords() const; |
| 184 return (top_ - FirstObjectStart()) >> kWordSizeLog2; | |
| 185 } | |
| 186 int64_t CapacityInWords() const { return to_->size_in_words(); } | 205 int64_t CapacityInWords() const { return to_->size_in_words(); } |
| 187 int64_t ExternalInWords() const { return external_size_ >> kWordSizeLog2; } | 206 int64_t ExternalInWords() const { return external_size_ >> kWordSizeLog2; } |
| 188 SpaceUsage GetCurrentUsage() const { | 207 SpaceUsage GetCurrentUsage() const { |
| 189 SpaceUsage usage; | 208 SpaceUsage usage; |
| 190 usage.used_in_words = UsedInWords(); | 209 usage.used_in_words = UsedInWords(); |
| 191 usage.capacity_in_words = CapacityInWords(); | 210 usage.capacity_in_words = CapacityInWords(); |
| 192 usage.external_in_words = ExternalInWords(); | 211 usage.external_in_words = ExternalInWords(); |
| 193 return usage; | 212 return usage; |
| 194 } | 213 } |
| 195 | 214 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 208 | 227 |
| 209 intptr_t collections() const { return collections_; } | 228 intptr_t collections() const { return collections_; } |
| 210 | 229 |
| 211 #ifndef PRODUCT | 230 #ifndef PRODUCT |
| 212 void PrintToJSONObject(JSONObject* object) const; | 231 void PrintToJSONObject(JSONObject* object) const; |
| 213 #endif // !PRODUCT | 232 #endif // !PRODUCT |
| 214 | 233 |
| 215 void AllocateExternal(intptr_t size); | 234 void AllocateExternal(intptr_t size); |
| 216 void FreeExternal(intptr_t size); | 235 void FreeExternal(intptr_t size); |
| 217 | 236 |
| 218 void FlushTLS() const; | 237 void MakeNewSpaceIterable() const; |
| 238 uword FirstObjectStart() const { return to_->start() | object_alignment_; } |
| 219 | 239 |
| 220 private: | 240 private: |
| 221 // Ids for time and data records in Heap::GCStats. | 241 // Ids for time and data records in Heap::GCStats. |
| 222 enum { | 242 enum { |
| 223 // Time | 243 // Time |
| 224 kDummyScavengeTime = 0, | 244 kDummyScavengeTime = 0, |
| 225 kSafePoint = 1, | 245 kSafePoint = 1, |
| 226 kVisitIsolateRoots = 2, | 246 kVisitIsolateRoots = 2, |
| 227 kIterateStoreBuffers = 3, | 247 kIterateStoreBuffers = 3, |
| 228 kProcessToSpace = 4, | 248 kProcessToSpace = 4, |
| 229 kIterateWeaks = 5, | 249 kIterateWeaks = 5, |
| 230 // Data | 250 // Data |
| 231 kStoreBufferEntries = 0, | 251 kStoreBufferEntries = 0, |
| 232 kDataUnused1 = 1, | 252 kDataUnused1 = 1, |
| 233 kDataUnused2 = 2, | 253 kDataUnused2 = 2, |
| 234 kToKBAfterStoreBuffer = 3 | 254 kToKBAfterStoreBuffer = 3 |
| 235 }; | 255 }; |
| 236 | 256 |
| 237 uword FirstObjectStart() const { return to_->start() | object_alignment_; } | |
| 238 SemiSpace* Prologue(Isolate* isolate, bool invoke_api_callbacks); | 257 SemiSpace* Prologue(Isolate* isolate, bool invoke_api_callbacks); |
| 239 void IterateStoreBuffers(Isolate* isolate, ScavengerVisitor* visitor); | 258 void IterateStoreBuffers(Isolate* isolate, ScavengerVisitor* visitor); |
| 240 void IterateObjectIdTable(Isolate* isolate, ScavengerVisitor* visitor); | 259 void IterateObjectIdTable(Isolate* isolate, ScavengerVisitor* visitor); |
| 241 void IterateRoots(Isolate* isolate, ScavengerVisitor* visitor); | 260 void IterateRoots(Isolate* isolate, ScavengerVisitor* visitor); |
| 242 void IterateWeakProperties(Isolate* isolate, ScavengerVisitor* visitor); | 261 void IterateWeakProperties(Isolate* isolate, ScavengerVisitor* visitor); |
| 243 void IterateWeakReferences(Isolate* isolate, ScavengerVisitor* visitor); | 262 void IterateWeakReferences(Isolate* isolate, ScavengerVisitor* visitor); |
| 244 void IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor); | 263 void IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor); |
| 245 void ProcessToSpace(ScavengerVisitor* visitor); | 264 void ProcessToSpace(ScavengerVisitor* visitor); |
| 246 void EnqueueWeakProperty(RawWeakProperty* raw_weak); | 265 void EnqueueWeakProperty(RawWeakProperty* raw_weak); |
| 247 uword ProcessWeakProperty(RawWeakProperty* raw_weak, | 266 uword ProcessWeakProperty(RawWeakProperty* raw_weak, |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 | 335 |
| 317 friend class ScavengerVisitor; | 336 friend class ScavengerVisitor; |
| 318 friend class ScavengerWeakVisitor; | 337 friend class ScavengerWeakVisitor; |
| 319 | 338 |
| 320 DISALLOW_COPY_AND_ASSIGN(Scavenger); | 339 DISALLOW_COPY_AND_ASSIGN(Scavenger); |
| 321 }; | 340 }; |
| 322 | 341 |
| 323 } // namespace dart | 342 } // namespace dart |
| 324 | 343 |
| 325 #endif // RUNTIME_VM_SCAVENGER_H_ | 344 #endif // RUNTIME_VM_SCAVENGER_H_ |
| OLD | NEW |