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 uword FlushTLS() const; |
| 238 void UnflushTLS(uword value) const; |
| 239 uword FirstObjectStart() const { return to_->start() | object_alignment_; } |
219 | 240 |
220 private: | 241 private: |
221 // Ids for time and data records in Heap::GCStats. | 242 // Ids for time and data records in Heap::GCStats. |
222 enum { | 243 enum { |
223 // Time | 244 // Time |
224 kDummyScavengeTime = 0, | 245 kDummyScavengeTime = 0, |
225 kSafePoint = 1, | 246 kSafePoint = 1, |
226 kVisitIsolateRoots = 2, | 247 kVisitIsolateRoots = 2, |
227 kIterateStoreBuffers = 3, | 248 kIterateStoreBuffers = 3, |
228 kProcessToSpace = 4, | 249 kProcessToSpace = 4, |
229 kIterateWeaks = 5, | 250 kIterateWeaks = 5, |
230 // Data | 251 // Data |
231 kStoreBufferEntries = 0, | 252 kStoreBufferEntries = 0, |
232 kDataUnused1 = 1, | 253 kDataUnused1 = 1, |
233 kDataUnused2 = 2, | 254 kDataUnused2 = 2, |
234 kToKBAfterStoreBuffer = 3 | 255 kToKBAfterStoreBuffer = 3 |
235 }; | 256 }; |
236 | 257 |
237 uword FirstObjectStart() const { return to_->start() | object_alignment_; } | |
238 SemiSpace* Prologue(Isolate* isolate, bool invoke_api_callbacks); | 258 SemiSpace* Prologue(Isolate* isolate, bool invoke_api_callbacks); |
239 void IterateStoreBuffers(Isolate* isolate, ScavengerVisitor* visitor); | 259 void IterateStoreBuffers(Isolate* isolate, ScavengerVisitor* visitor); |
240 void IterateObjectIdTable(Isolate* isolate, ScavengerVisitor* visitor); | 260 void IterateObjectIdTable(Isolate* isolate, ScavengerVisitor* visitor); |
241 void IterateRoots(Isolate* isolate, ScavengerVisitor* visitor); | 261 void IterateRoots(Isolate* isolate, ScavengerVisitor* visitor); |
242 void IterateWeakProperties(Isolate* isolate, ScavengerVisitor* visitor); | 262 void IterateWeakProperties(Isolate* isolate, ScavengerVisitor* visitor); |
243 void IterateWeakReferences(Isolate* isolate, ScavengerVisitor* visitor); | 263 void IterateWeakReferences(Isolate* isolate, ScavengerVisitor* visitor); |
244 void IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor); | 264 void IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor); |
245 void ProcessToSpace(ScavengerVisitor* visitor); | 265 void ProcessToSpace(ScavengerVisitor* visitor); |
246 void EnqueueWeakProperty(RawWeakProperty* raw_weak); | 266 void EnqueueWeakProperty(RawWeakProperty* raw_weak); |
247 uword ProcessWeakProperty(RawWeakProperty* raw_weak, | 267 uword ProcessWeakProperty(RawWeakProperty* raw_weak, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 | 336 |
317 friend class ScavengerVisitor; | 337 friend class ScavengerVisitor; |
318 friend class ScavengerWeakVisitor; | 338 friend class ScavengerWeakVisitor; |
319 | 339 |
320 DISALLOW_COPY_AND_ASSIGN(Scavenger); | 340 DISALLOW_COPY_AND_ASSIGN(Scavenger); |
321 }; | 341 }; |
322 | 342 |
323 } // namespace dart | 343 } // namespace dart |
324 | 344 |
325 #endif // RUNTIME_VM_SCAVENGER_H_ | 345 #endif // RUNTIME_VM_SCAVENGER_H_ |
OLD | NEW |