OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 #include "vm/scavenger.h" | 5 #include "vm/scavenger.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 for (DelaySet::iterator it = ret.first; it != ret.second; ++it) { | 178 for (DelaySet::iterator it = ret.first; it != ret.second; ++it) { |
179 // Remember the delayed WeakProperty. These objects have been | 179 // Remember the delayed WeakProperty. These objects have been |
180 // forwarded, but have not been scavenged because their key was not | 180 // forwarded, but have not been scavenged because their key was not |
181 // known to be reachable. Now that the key object is known to be | 181 // known to be reachable. Now that the key object is known to be |
182 // reachable, we need to visit its key and value pointers. | 182 // reachable, we need to visit its key and value pointers. |
183 delayed_weak_stack_.Add(it->second); | 183 delayed_weak_stack_.Add(it->second); |
184 } | 184 } |
185 delay_set_.erase(ret.first, ret.second); | 185 delay_set_.erase(ret.first, ret.second); |
186 } | 186 } |
187 intptr_t size = raw_obj->Size(); | 187 intptr_t size = raw_obj->Size(); |
| 188 intptr_t cid = raw_obj->GetClassId(); |
| 189 ClassTable* class_table = isolate()->class_table(); |
188 // Check whether object should be promoted. | 190 // Check whether object should be promoted. |
189 if (scavenger_->survivor_end_ <= raw_addr) { | 191 if (scavenger_->survivor_end_ <= raw_addr) { |
190 // Not a survivor of a previous scavenge. Just copy the object into the | 192 // Not a survivor of a previous scavenge. Just copy the object into the |
191 // to space. | 193 // to space. |
192 new_addr = scavenger_->TryAllocate(size); | 194 new_addr = scavenger_->TryAllocate(size); |
| 195 class_table->UpdateLiveNew(cid, size); |
193 } else { | 196 } else { |
194 // TODO(iposva): Experiment with less aggressive promotion. For example | 197 // TODO(iposva): Experiment with less aggressive promotion. For example |
195 // a coin toss determines if an object is promoted or whether it should | 198 // a coin toss determines if an object is promoted or whether it should |
196 // survive in this generation. | 199 // survive in this generation. |
197 // | 200 // |
198 // This object is a survivor of a previous scavenge. Attempt to promote | 201 // This object is a survivor of a previous scavenge. Attempt to promote |
199 // the object. | 202 // the object. |
200 new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_); | 203 new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_); |
201 if (new_addr != 0) { | 204 if (new_addr != 0) { |
202 // If promotion succeeded then we need to remember it so that it can | 205 // If promotion succeeded then we need to remember it so that it can |
203 // be traversed later. | 206 // be traversed later. |
204 scavenger_->PushToPromotedStack(new_addr); | 207 scavenger_->PushToPromotedStack(new_addr); |
205 bytes_promoted_ += size; | 208 bytes_promoted_ += size; |
| 209 class_table->UpdateAllocatedOld(cid, size); |
206 } else if (!scavenger_->had_promotion_failure_) { | 210 } else if (!scavenger_->had_promotion_failure_) { |
207 // Signal a promotion failure and set the growth policy for | 211 // Signal a promotion failure and set the growth policy for |
208 // this, and all subsequent promotion allocations, to force | 212 // this, and all subsequent promotion allocations, to force |
209 // growth. | 213 // growth. |
210 scavenger_->had_promotion_failure_ = true; | 214 scavenger_->had_promotion_failure_ = true; |
211 growth_policy_ = PageSpace::kForceGrowth; | 215 growth_policy_ = PageSpace::kForceGrowth; |
212 new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_); | 216 new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_); |
213 if (new_addr != 0) { | 217 if (new_addr != 0) { |
214 scavenger_->PushToPromotedStack(new_addr); | 218 scavenger_->PushToPromotedStack(new_addr); |
215 bytes_promoted_ += size; | 219 bytes_promoted_ += size; |
| 220 class_table->UpdateAllocatedOld(cid, size); |
216 } else { | 221 } else { |
217 // Promotion did not succeed. Copy into the to space | 222 // Promotion did not succeed. Copy into the to space |
218 // instead. | 223 // instead. |
219 new_addr = scavenger_->TryAllocate(size); | 224 new_addr = scavenger_->TryAllocate(size); |
| 225 class_table->UpdateLiveNew(cid, size); |
220 } | 226 } |
221 } else { | 227 } else { |
222 ASSERT(growth_policy_ == PageSpace::kForceGrowth); | 228 ASSERT(growth_policy_ == PageSpace::kForceGrowth); |
223 // Promotion did not succeed. Copy into the to space instead. | 229 // Promotion did not succeed. Copy into the to space instead. |
224 new_addr = scavenger_->TryAllocate(size); | 230 new_addr = scavenger_->TryAllocate(size); |
| 231 class_table->UpdateLiveNew(cid, size); |
225 } | 232 } |
226 } | 233 } |
227 // During a scavenge we always succeed to at least copy all of the | 234 // During a scavenge we always succeed to at least copy all of the |
228 // current objects to the to space. | 235 // current objects to the to space. |
229 ASSERT(new_addr != 0); | 236 ASSERT(new_addr != 0); |
230 // Copy the object to the new location. | 237 // Copy the object to the new location. |
231 memmove(reinterpret_cast<void*>(new_addr), | 238 memmove(reinterpret_cast<void*>(new_addr), |
232 reinterpret_cast<void*>(raw_addr), | 239 reinterpret_cast<void*>(raw_addr), |
233 size); | 240 size); |
234 // Remember forwarding address. | 241 // Remember forwarding address. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 | 311 |
305 DISALLOW_COPY_AND_ASSIGN(VerifyStoreBufferPointerVisitor); | 312 DISALLOW_COPY_AND_ASSIGN(VerifyStoreBufferPointerVisitor); |
306 }; | 313 }; |
307 | 314 |
308 | 315 |
309 Scavenger::Scavenger(Heap* heap, | 316 Scavenger::Scavenger(Heap* heap, |
310 intptr_t max_capacity_in_words, | 317 intptr_t max_capacity_in_words, |
311 uword object_alignment) | 318 uword object_alignment) |
312 : heap_(heap), | 319 : heap_(heap), |
313 object_alignment_(object_alignment), | 320 object_alignment_(object_alignment), |
314 scavenging_(false) { | 321 scavenging_(false), |
| 322 gc_time_micros_(0), |
| 323 collections_(0) { |
315 // Verify assumptions about the first word in objects which the scavenger is | 324 // Verify assumptions about the first word in objects which the scavenger is |
316 // going to use for forwarding pointers. | 325 // going to use for forwarding pointers. |
317 ASSERT(Object::tags_offset() == 0); | 326 ASSERT(Object::tags_offset() == 0); |
318 | 327 |
319 // Allocate the virtual memory for this scavenge heap. | 328 // Allocate the virtual memory for this scavenge heap. |
320 space_ = VirtualMemory::Reserve(max_capacity_in_words << kWordSizeLog2); | 329 space_ = VirtualMemory::Reserve(max_capacity_in_words << kWordSizeLog2); |
321 if (space_ == NULL) { | 330 if (space_ == NULL) { |
322 FATAL("Out of memory.\n"); | 331 FATAL("Out of memory.\n"); |
323 } | 332 } |
324 | 333 |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 scavenging_ = false; | 710 scavenging_ = false; |
702 } | 711 } |
703 | 712 |
704 | 713 |
705 void Scavenger::WriteProtect(bool read_only) { | 714 void Scavenger::WriteProtect(bool read_only) { |
706 space_->Protect( | 715 space_->Protect( |
707 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); | 716 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); |
708 } | 717 } |
709 | 718 |
710 | 719 |
| 720 void Scavenger::PrintToJSONObject(JSONObject* object) { |
| 721 JSONObject space(object, "new"); |
| 722 space.AddProperty("type", "@Scavenger"); |
| 723 space.AddProperty("id", "heaps/new"); |
| 724 space.AddProperty("name", "Scavenger"); |
| 725 space.AddProperty("user_name", "new"); |
| 726 space.AddProperty("collections", collections()); |
| 727 space.AddProperty("used", UsedInWords() * kWordSize); |
| 728 space.AddProperty("capacity", CapacityInWords() * kWordSize); |
| 729 space.AddProperty("time", RoundMicrosecondsToSeconds(gc_time_micros())); |
| 730 } |
| 731 |
| 732 |
711 } // namespace dart | 733 } // namespace dart |
OLD | NEW |