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