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