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 AllocateGC(intptr_t size) { |
127 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 127 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
128 ASSERT(heap_ != Dart::vm_isolate()->heap()); | 128 ASSERT(heap_ != Dart::vm_isolate()->heap()); |
| 129 ASSERT(scavenging_); |
| 130 uword result = top_; |
| 131 intptr_t remaining = end_ - top_; |
| 132 |
| 133 // This allocation happens only in GC and only when copying objects to |
| 134 // the new to_ space. It must succeed. |
| 135 ASSERT(size <= remaining); |
| 136 ASSERT(to_->Contains(result)); |
| 137 ASSERT((result & kObjectAlignmentMask) == object_alignment_); |
| 138 top_ += size; |
| 139 ASSERT(to_->Contains(top_) || (top_ == to_->end())); |
| 140 return result; |
| 141 } |
| 142 |
| 143 uword TryAllocateInTLAB(Thread* thread, intptr_t size) { |
| 144 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 145 ASSERT(heap_ != Dart::vm_isolate()->heap()); |
| 146 ASSERT(thread->IsMutatorThread()); |
| 147 ASSERT(thread->isolate()->IsMutatorThreadScheduled()); |
129 #if defined(DEBUG) | 148 #if defined(DEBUG) |
130 if (FLAG_gc_at_alloc && !scavenging_) { | 149 if (FLAG_gc_at_alloc) { |
| 150 ASSERT(!scavenging_); |
131 Scavenge(); | 151 Scavenge(); |
132 } | 152 } |
133 #endif | 153 #endif |
134 uword result = top_; | 154 uword top = thread->top(); |
135 intptr_t remaining = end_ - top_; | 155 uword end = thread->end(); |
| 156 uword result = top; |
| 157 intptr_t remaining = end - top; |
136 if (remaining < size) { | 158 if (remaining < size) { |
137 return 0; | 159 return 0; |
138 } | 160 } |
139 ASSERT(to_->Contains(result)); | 161 ASSERT(to_->Contains(result)); |
140 ASSERT((result & kObjectAlignmentMask) == object_alignment_); | 162 ASSERT((result & kObjectAlignmentMask) == object_alignment_); |
141 | 163 top += size; |
142 top_ += size; | 164 ASSERT(to_->Contains(top) || (top == to_->end())); |
143 ASSERT(to_->Contains(top_) || (top_ == to_->end())); | 165 thread->set_top(top); |
144 return result; | 166 return result; |
145 } | 167 } |
146 | 168 |
147 // Collect the garbage in this scavenger. | 169 // Collect the garbage in this scavenger. |
148 void Scavenge(); | 170 void Scavenge(); |
149 void Scavenge(bool invoke_api_callbacks); | 171 void Scavenge(bool invoke_api_callbacks); |
150 | 172 |
151 // Promote all live objects. | 173 // Promote all live objects. |
152 void Evacuate(); | 174 void Evacuate(); |
153 | 175 |
154 // Accessors to generate code for inlined allocation. | 176 uword top() { return top_; } |
155 uword* TopAddress() { return &top_; } | 177 uword end() { return end_; } |
156 uword* EndAddress() { return &end_; } | 178 |
157 static intptr_t top_offset() { return OFFSET_OF(Scavenger, top_); } | 179 void set_top(uword value) { top_ = value; } |
158 static intptr_t end_offset() { return OFFSET_OF(Scavenger, end_); } | 180 void set_end(uword value) { |
| 181 ASSERT(to_->end() == value); |
| 182 end_ = value; |
| 183 } |
159 | 184 |
160 int64_t UsedInWords() const { | 185 int64_t UsedInWords() const { |
161 return (top_ - FirstObjectStart()) >> kWordSizeLog2; | 186 return (top_ - FirstObjectStart()) >> kWordSizeLog2; |
162 } | 187 } |
163 int64_t CapacityInWords() const { return to_->size_in_words(); } | 188 int64_t CapacityInWords() const { return to_->size_in_words(); } |
164 int64_t ExternalInWords() const { return external_size_ >> kWordSizeLog2; } | 189 int64_t ExternalInWords() const { return external_size_ >> kWordSizeLog2; } |
165 SpaceUsage GetCurrentUsage() const { | 190 SpaceUsage GetCurrentUsage() const { |
166 SpaceUsage usage; | 191 SpaceUsage usage; |
167 usage.used_in_words = UsedInWords(); | 192 usage.used_in_words = UsedInWords(); |
168 usage.capacity_in_words = CapacityInWords(); | 193 usage.capacity_in_words = CapacityInWords(); |
(...skipping 16 matching lines...) Expand all Loading... |
185 | 210 |
186 intptr_t collections() const { return collections_; } | 211 intptr_t collections() const { return collections_; } |
187 | 212 |
188 #ifndef PRODUCT | 213 #ifndef PRODUCT |
189 void PrintToJSONObject(JSONObject* object) const; | 214 void PrintToJSONObject(JSONObject* object) const; |
190 #endif // !PRODUCT | 215 #endif // !PRODUCT |
191 | 216 |
192 void AllocateExternal(intptr_t size); | 217 void AllocateExternal(intptr_t size); |
193 void FreeExternal(intptr_t size); | 218 void FreeExternal(intptr_t size); |
194 | 219 |
| 220 void FlushTLS() const; |
| 221 |
195 private: | 222 private: |
196 // Ids for time and data records in Heap::GCStats. | 223 // Ids for time and data records in Heap::GCStats. |
197 enum { | 224 enum { |
198 // Time | 225 // Time |
199 kDummyScavengeTime = 0, | 226 kDummyScavengeTime = 0, |
200 kSafePoint = 1, | 227 kSafePoint = 1, |
201 kVisitIsolateRoots = 2, | 228 kVisitIsolateRoots = 2, |
202 kIterateStoreBuffers = 3, | 229 kIterateStoreBuffers = 3, |
203 kProcessToSpace = 4, | 230 kProcessToSpace = 4, |
204 kIterateWeaks = 5, | 231 kIterateWeaks = 5, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 return end_ < to_->end(); | 274 return end_ < to_->end(); |
248 } | 275 } |
249 | 276 |
250 void UpdateMaxHeapCapacity(); | 277 void UpdateMaxHeapCapacity(); |
251 void UpdateMaxHeapUsage(); | 278 void UpdateMaxHeapUsage(); |
252 | 279 |
253 void ProcessWeakReferences(); | 280 void ProcessWeakReferences(); |
254 | 281 |
255 intptr_t NewSizeInWords(intptr_t old_size_in_words) const; | 282 intptr_t NewSizeInWords(intptr_t old_size_in_words) const; |
256 | 283 |
257 // Accessed from generated code. | |
258 // ** This block of fields must come first! ** | |
259 // 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. | |
261 // We use only word-sized fields to avoid differences in struct packing on the | |
262 // different architectures. See also CheckOffsets in dart.cc. | |
263 uword top_; | 284 uword top_; |
264 uword end_; | 285 uword end_; |
265 | 286 |
266 SemiSpace* to_; | 287 SemiSpace* to_; |
267 | 288 |
268 Heap* heap_; | 289 Heap* heap_; |
269 | 290 |
270 // A pointer to the first unscanned object. Scanning completes when | 291 // A pointer to the first unscanned object. Scanning completes when |
271 // this value meets the allocation top. | 292 // this value meets the allocation top. |
272 uword resolved_top_; | 293 uword resolved_top_; |
(...skipping 24 matching lines...) Expand all Loading... |
297 | 318 |
298 friend class ScavengerVisitor; | 319 friend class ScavengerVisitor; |
299 friend class ScavengerWeakVisitor; | 320 friend class ScavengerWeakVisitor; |
300 | 321 |
301 DISALLOW_COPY_AND_ASSIGN(Scavenger); | 322 DISALLOW_COPY_AND_ASSIGN(Scavenger); |
302 }; | 323 }; |
303 | 324 |
304 } // namespace dart | 325 } // namespace dart |
305 | 326 |
306 #endif // RUNTIME_VM_SCAVENGER_H_ | 327 #endif // RUNTIME_VM_SCAVENGER_H_ |
OLD | NEW |