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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 ~Scavenger(); | 116 ~Scavenger(); |
117 | 117 |
118 // Check whether this Scavenger contains this address. | 118 // Check whether this Scavenger contains this address. |
119 // During scavenging both the to and from spaces contain "legal" objects. | 119 // During scavenging both the to and from spaces contain "legal" objects. |
120 // 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 |
121 // be part of the surviving objects. | 121 // be part of the surviving objects. |
122 bool Contains(uword addr) const { return to_->Contains(addr); } | 122 bool Contains(uword addr) const { return to_->Contains(addr); } |
123 | 123 |
124 RawObject* FindObject(FindObjectVisitor* visitor) const; | 124 RawObject* FindObject(FindObjectVisitor* visitor) const; |
125 | 125 |
126 uword TryAllocate(intptr_t size) { | 126 uword TryAllocate(intptr_t size) { return TryAllocateGC(size); } |
127 | |
128 uword TryAllocateGC(intptr_t size) { | |
127 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 129 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
128 ASSERT(heap_ != Dart::vm_isolate()->heap()); | 130 ASSERT(heap_ != Dart::vm_isolate()->heap()); |
131 | |
129 #if defined(DEBUG) | 132 #if defined(DEBUG) |
130 if (FLAG_gc_at_alloc && !scavenging_) { | 133 if (FLAG_gc_at_alloc && !scavenging_) { |
131 Scavenge(); | 134 Scavenge(); |
132 } | 135 } |
133 #endif | 136 #endif |
137 | |
134 uword result = top_; | 138 uword result = top_; |
135 intptr_t remaining = end_ - top_; | 139 intptr_t remaining = end_ - top_; |
136 if (remaining < size) { | 140 if (remaining < size) { |
137 return 0; | 141 return 0; |
138 } | 142 } |
139 ASSERT(to_->Contains(result)); | 143 ASSERT(to_->Contains(result)); |
140 ASSERT((result & kObjectAlignmentMask) == object_alignment_); | 144 ASSERT((result & kObjectAlignmentMask) == object_alignment_); |
141 | 145 |
142 top_ += size; | 146 top_ += size; |
143 ASSERT(to_->Contains(top_) || (top_ == to_->end())); | 147 ASSERT(to_->Contains(top_) || (top_ == to_->end())); |
148 | |
144 return result; | 149 return result; |
145 } | 150 } |
146 | 151 |
152 uword TryAllocateInTLAB(Thread* thread, intptr_t size) { | |
153 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | |
154 ASSERT(heap_ != Dart::vm_isolate()->heap()); | |
155 | |
156 ASSERT(thread->IsMutatorThread()); | |
157 ASSERT(thread->heap() == heap_); | |
158 | |
159 #if defined(DEBUG) | |
160 if (FLAG_gc_at_alloc && !scavenging_) { | |
161 Scavenge(); | |
162 } | |
163 #endif | |
164 | |
165 uword top = thread->top(); | |
166 uword end = thread->end(); | |
167 | |
168 uword result = top; | |
169 intptr_t remaining = end - top; | |
170 if (remaining < size) { | |
171 return 0; | |
172 } | |
173 | |
174 ASSERT(to_->Contains(result)); | |
175 ASSERT((result & kObjectAlignmentMask) == object_alignment_); | |
176 | |
177 top += size; | |
178 ASSERT(to_->Contains(top) || (top == to_->end())); | |
179 | |
180 thread->set_top(top); | |
181 return result; | |
182 } | |
183 | |
147 // Collect the garbage in this scavenger. | 184 // Collect the garbage in this scavenger. |
148 void Scavenge(); | 185 void Scavenge(); |
149 void Scavenge(bool invoke_api_callbacks); | 186 void Scavenge(bool invoke_api_callbacks); |
150 | 187 |
151 // Promote all live objects. | 188 // Promote all live objects. |
152 void Evacuate(); | 189 void Evacuate(Thread* thread); |
153 | 190 |
154 // Accessors to generate code for inlined allocation. | 191 // Accessors to generate code for inlined allocation. |
rmacnak
2017/07/12 17:10:22
Remove TopAddress and EndAddress.
danunez
2017/07/12 18:23:38
Done.
| |
155 uword* TopAddress() { return &top_; } | 192 uword* TopAddress() { return &top_; } |
156 uword* EndAddress() { return &end_; } | 193 uword* EndAddress() { return &end_; } |
157 static intptr_t top_offset() { return OFFSET_OF(Scavenger, top_); } | 194 |
158 static intptr_t end_offset() { return OFFSET_OF(Scavenger, end_); } | 195 uword top() { return top_; } |
196 uword end() { return end_; } | |
197 | |
198 void set_top(uword value) { top_ = value; } | |
199 void set_end(uword value) { | |
200 ASSERT(to_->end() == value); | |
201 end_ = value; | |
202 } | |
159 | 203 |
160 int64_t UsedInWords() const { | 204 int64_t UsedInWords() const { |
161 return (top_ - FirstObjectStart()) >> kWordSizeLog2; | 205 return (top_ - FirstObjectStart()) >> kWordSizeLog2; |
162 } | 206 } |
163 int64_t CapacityInWords() const { return to_->size_in_words(); } | 207 int64_t CapacityInWords() const { return to_->size_in_words(); } |
164 int64_t ExternalInWords() const { return external_size_ >> kWordSizeLog2; } | 208 int64_t ExternalInWords() const { return external_size_ >> kWordSizeLog2; } |
165 SpaceUsage GetCurrentUsage() const { | 209 SpaceUsage GetCurrentUsage() const { |
166 SpaceUsage usage; | 210 SpaceUsage usage; |
167 usage.used_in_words = UsedInWords(); | 211 usage.used_in_words = UsedInWords(); |
168 usage.capacity_in_words = CapacityInWords(); | 212 usage.capacity_in_words = CapacityInWords(); |
(...skipping 16 matching lines...) Expand all Loading... | |
185 | 229 |
186 intptr_t collections() const { return collections_; } | 230 intptr_t collections() const { return collections_; } |
187 | 231 |
188 #ifndef PRODUCT | 232 #ifndef PRODUCT |
189 void PrintToJSONObject(JSONObject* object) const; | 233 void PrintToJSONObject(JSONObject* object) const; |
190 #endif // !PRODUCT | 234 #endif // !PRODUCT |
191 | 235 |
192 void AllocateExternal(intptr_t size); | 236 void AllocateExternal(intptr_t size); |
193 void FreeExternal(intptr_t size); | 237 void FreeExternal(intptr_t size); |
194 | 238 |
239 void FlushTLS() const; | |
240 | |
195 private: | 241 private: |
196 // Ids for time and data records in Heap::GCStats. | 242 // Ids for time and data records in Heap::GCStats. |
197 enum { | 243 enum { |
198 // Time | 244 // Time |
199 kDummyScavengeTime = 0, | 245 kDummyScavengeTime = 0, |
200 kSafePoint = 1, | 246 kSafePoint = 1, |
201 kVisitIsolateRoots = 2, | 247 kVisitIsolateRoots = 2, |
202 kIterateStoreBuffers = 3, | 248 kIterateStoreBuffers = 3, |
203 kProcessToSpace = 4, | 249 kProcessToSpace = 4, |
204 kIterateWeaks = 5, | 250 kIterateWeaks = 5, |
(...skipping 19 matching lines...) Expand all Loading... | |
224 void Epilogue(Isolate* isolate, SemiSpace* from, bool invoke_api_callbacks); | 270 void Epilogue(Isolate* isolate, SemiSpace* from, bool invoke_api_callbacks); |
225 | 271 |
226 bool IsUnreachable(RawObject** p); | 272 bool IsUnreachable(RawObject** p); |
227 | 273 |
228 // During a scavenge we need to remember the promoted objects. | 274 // During a scavenge we need to remember the promoted objects. |
229 // This is implemented as a stack of objects at the end of the to space. As | 275 // This is implemented as a stack of objects at the end of the to space. As |
230 // object sizes are always greater than sizeof(uword) and promoted objects do | 276 // object sizes are always greater than sizeof(uword) and promoted objects do |
231 // not consume space in the to space they leave enough room for this stack. | 277 // not consume space in the to space they leave enough room for this stack. |
232 void PushToPromotedStack(uword addr) { | 278 void PushToPromotedStack(uword addr) { |
233 ASSERT(scavenging_); | 279 ASSERT(scavenging_); |
280 | |
rmacnak
2017/07/12 17:10:22
Remove spurious whitespace changes.
danunez
2017/07/12 18:23:38
Done.
| |
234 end_ -= sizeof(addr); | 281 end_ -= sizeof(addr); |
282 | |
235 ASSERT(end_ > top_); | 283 ASSERT(end_ > top_); |
236 *reinterpret_cast<uword*>(end_) = addr; | 284 *reinterpret_cast<uword*>(end_) = addr; |
237 } | 285 } |
238 uword PopFromPromotedStack() { | 286 uword PopFromPromotedStack() { |
239 ASSERT(scavenging_); | 287 ASSERT(scavenging_); |
288 | |
240 uword result = *reinterpret_cast<uword*>(end_); | 289 uword result = *reinterpret_cast<uword*>(end_); |
241 end_ += sizeof(result); | 290 end_ += sizeof(result); |
291 | |
242 ASSERT(end_ <= to_->end()); | 292 ASSERT(end_ <= to_->end()); |
243 return result; | 293 return result; |
244 } | 294 } |
245 bool PromotedStackHasMore() const { | 295 bool PromotedStackHasMore() const { |
246 ASSERT(scavenging_); | 296 ASSERT(scavenging_); |
247 return end_ < to_->end(); | 297 return end_ < to_->end(); |
248 } | 298 } |
249 | 299 |
250 void UpdateMaxHeapCapacity(); | 300 void UpdateMaxHeapCapacity(); |
251 void UpdateMaxHeapUsage(); | 301 void UpdateMaxHeapUsage(); |
252 | 302 |
253 void ProcessWeakReferences(); | 303 void ProcessWeakReferences(); |
254 | 304 |
255 intptr_t NewSizeInWords(intptr_t old_size_in_words) const; | 305 intptr_t NewSizeInWords(intptr_t old_size_in_words) const; |
256 | 306 |
257 // Accessed from generated code. | 307 // Accessed from generated code. |
rmacnak
2017/07/12 17:10:22
Remove comment. No longer accessed from generated
danunez
2017/07/12 18:23:38
Done.
| |
258 // ** This block of fields must come first! ** | 308 // ** This block of fields must come first! ** |
259 // For AOT cross-compilation, we rely on these members having the same offsets | 309 // For AOT cross-compilation, we rely on these members having the same offsets |
260 // in SIMARM(IA32) and ARM, and the same offsets in SIMARM64(X64) and ARM64. | 310 // in SIMARM(IA32) and ARM, and the same offsets in SIMARM64(X64) and ARM64. |
261 // We use only word-sized fields to avoid differences in struct packing on the | 311 // We use only word-sized fields to avoid differences in struct packing on the |
262 // different architectures. See also CheckOffsets in dart.cc. | 312 // different architectures. See also CheckOffsets in dart.cc. |
263 uword top_; | 313 uword top_; |
264 uword end_; | 314 uword end_; |
265 | 315 |
266 SemiSpace* to_; | 316 SemiSpace* to_; |
267 | 317 |
(...skipping 19 matching lines...) Expand all Loading... | |
287 | 337 |
288 int64_t gc_time_micros_; | 338 int64_t gc_time_micros_; |
289 intptr_t collections_; | 339 intptr_t collections_; |
290 static const int kStatsHistoryCapacity = 2; | 340 static const int kStatsHistoryCapacity = 2; |
291 RingBuffer<ScavengeStats, kStatsHistoryCapacity> stats_history_; | 341 RingBuffer<ScavengeStats, kStatsHistoryCapacity> stats_history_; |
292 | 342 |
293 // The total size of external data associated with objects in this scavenger. | 343 // The total size of external data associated with objects in this scavenger. |
294 intptr_t external_size_; | 344 intptr_t external_size_; |
295 | 345 |
296 bool failed_to_promote_; | 346 bool failed_to_promote_; |
347 Mutex* space_lock_; | |
297 | 348 |
298 friend class ScavengerVisitor; | 349 friend class ScavengerVisitor; |
299 friend class ScavengerWeakVisitor; | 350 friend class ScavengerWeakVisitor; |
300 | 351 |
301 DISALLOW_COPY_AND_ASSIGN(Scavenger); | 352 DISALLOW_COPY_AND_ASSIGN(Scavenger); |
302 }; | 353 }; |
303 | 354 |
304 } // namespace dart | 355 } // namespace dart |
305 | 356 |
306 #endif // RUNTIME_VM_SCAVENGER_H_ | 357 #endif // RUNTIME_VM_SCAVENGER_H_ |
OLD | NEW |