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