| 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 "vm/dart.h" | 7 #include "vm/dart.h" | 
| 8 #include "vm/dart_api_state.h" | 8 #include "vm/dart_api_state.h" | 
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" | 
| 10 #include "vm/lockers.h" | 10 #include "vm/lockers.h" | 
| 11 #include "vm/object.h" | 11 #include "vm/object.h" | 
| 12 #include "vm/object_id_ring.h" | 12 #include "vm/object_id_ring.h" | 
| 13 #include "vm/safepoint.h" | 13 #include "vm/safepoint.h" | 
| 14 #include "vm/stack_frame.h" | 14 #include "vm/stack_frame.h" | 
| 15 #include "vm/store_buffer.h" | 15 #include "vm/store_buffer.h" | 
| 16 #include "vm/thread_registry.h" | 16 #include "vm/thread_registry.h" | 
| 17 #include "vm/timeline.h" | 17 #include "vm/timeline.h" | 
| 18 #include "vm/verified_memory.h" |  | 
| 19 #include "vm/verifier.h" | 18 #include "vm/verifier.h" | 
| 20 #include "vm/visitor.h" | 19 #include "vm/visitor.h" | 
| 21 #include "vm/weak_table.h" | 20 #include "vm/weak_table.h" | 
| 22 | 21 | 
| 23 namespace dart { | 22 namespace dart { | 
| 24 | 23 | 
| 25 DEFINE_FLAG(int, early_tenuring_threshold, 66, | 24 DEFINE_FLAG(int, early_tenuring_threshold, 66, | 
| 26             "When more than this percentage of promotion candidates survive, " | 25             "When more than this percentage of promotion candidates survive, " | 
| 27             "promote all survivors of next scavenge."); | 26             "promote all survivors of next scavenge."); | 
| 28 DEFINE_FLAG(int, new_gen_garbage_threshold, 90, | 27 DEFINE_FLAG(int, new_gen_garbage_threshold, 90, | 
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 154           class_table->UpdateLiveNew(cid, size); | 153           class_table->UpdateLiveNew(cid, size); | 
| 155         } | 154         } | 
| 156       } | 155       } | 
| 157       // During a scavenge we always succeed to at least copy all of the | 156       // During a scavenge we always succeed to at least copy all of the | 
| 158       // current objects to the to space. | 157       // current objects to the to space. | 
| 159       ASSERT(new_addr != 0); | 158       ASSERT(new_addr != 0); | 
| 160       // Copy the object to the new location. | 159       // Copy the object to the new location. | 
| 161       memmove(reinterpret_cast<void*>(new_addr), | 160       memmove(reinterpret_cast<void*>(new_addr), | 
| 162               reinterpret_cast<void*>(raw_addr), | 161               reinterpret_cast<void*>(raw_addr), | 
| 163               size); | 162               size); | 
| 164       VerifiedMemory::Accept(new_addr, size); |  | 
| 165       // Remember forwarding address. | 163       // Remember forwarding address. | 
| 166       ForwardTo(raw_addr, new_addr); | 164       ForwardTo(raw_addr, new_addr); | 
| 167     } | 165     } | 
| 168     // Update the reference. | 166     // Update the reference. | 
| 169     RawObject* new_obj = RawObject::FromAddr(new_addr); | 167     RawObject* new_obj = RawObject::FromAddr(new_addr); | 
| 170     *p = new_obj; | 168     *p = new_obj; | 
| 171     // Update the store buffer as needed. | 169     // Update the store buffer as needed. | 
| 172     if (visiting_old_object_ != NULL) { | 170     if (visiting_old_object_ != NULL) { | 
| 173       VerifiedMemory::Accept(reinterpret_cast<uword>(p), sizeof(*p)); |  | 
| 174       UpdateStoreBuffer(p, new_obj); | 171       UpdateStoreBuffer(p, new_obj); | 
| 175     } | 172     } | 
| 176   } | 173   } | 
| 177 | 174 | 
| 178   Thread* thread_; | 175   Thread* thread_; | 
| 179   Scavenger* scavenger_; | 176   Scavenger* scavenger_; | 
| 180   SemiSpace* from_; | 177   SemiSpace* from_; | 
| 181   Heap* heap_; | 178   Heap* heap_; | 
| 182   Heap* vm_heap_; | 179   Heap* vm_heap_; | 
| 183   PageSpace* page_space_; | 180   PageSpace* page_space_; | 
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 282     if (cache_ != NULL && cache_->size_in_words() == size_in_words) { | 279     if (cache_ != NULL && cache_->size_in_words() == size_in_words) { | 
| 283       SemiSpace* result = cache_; | 280       SemiSpace* result = cache_; | 
| 284       cache_ = NULL; | 281       cache_ = NULL; | 
| 285       return result; | 282       return result; | 
| 286     } | 283     } | 
| 287   } | 284   } | 
| 288   if (size_in_words == 0) { | 285   if (size_in_words == 0) { | 
| 289     return new SemiSpace(NULL); | 286     return new SemiSpace(NULL); | 
| 290   } else { | 287   } else { | 
| 291     intptr_t size_in_bytes = size_in_words << kWordSizeLog2; | 288     intptr_t size_in_bytes = size_in_words << kWordSizeLog2; | 
| 292     VirtualMemory* reserved = VerifiedMemory::Reserve(size_in_bytes); | 289     VirtualMemory* reserved = VirtualMemory::Reserve(size_in_bytes); | 
| 293     if ((reserved == NULL) || !reserved->Commit(false)) {  // Not executable. | 290     if ((reserved == NULL) || !reserved->Commit(false)) {  // Not executable. | 
| 294       // TODO(koda): If cache_ is not empty, we could try to delete it. | 291       // TODO(koda): If cache_ is not empty, we could try to delete it. | 
| 295       delete reserved; | 292       delete reserved; | 
| 296       return NULL; | 293       return NULL; | 
| 297     } | 294     } | 
| 298 #if defined(DEBUG) | 295 #if defined(DEBUG) | 
| 299     memset(reserved->address(), Heap::kZapByte, size_in_bytes); | 296     memset(reserved->address(), Heap::kZapByte, size_in_bytes); | 
| 300     VerifiedMemory::Accept(reserved->start(), size_in_bytes); |  | 
| 301 #endif  // defined(DEBUG) | 297 #endif  // defined(DEBUG) | 
| 302     return new SemiSpace(reserved); | 298     return new SemiSpace(reserved); | 
| 303   } | 299   } | 
| 304 } | 300 } | 
| 305 | 301 | 
| 306 | 302 | 
| 307 void SemiSpace::Delete() { | 303 void SemiSpace::Delete() { | 
| 308 #ifdef DEBUG | 304 #ifdef DEBUG | 
| 309   if (reserved_ != NULL) { | 305   if (reserved_ != NULL) { | 
| 310     const intptr_t size_in_bytes = size_in_words() << kWordSizeLog2; | 306     const intptr_t size_in_bytes = size_in_words() << kWordSizeLog2; | 
| 311     memset(reserved_->address(), Heap::kZapByte, size_in_bytes); | 307     memset(reserved_->address(), Heap::kZapByte, size_in_bytes); | 
| 312     VerifiedMemory::Accept(reserved_->start(), size_in_bytes); |  | 
| 313   } | 308   } | 
| 314 #endif | 309 #endif | 
| 315   SemiSpace* old_cache = NULL; | 310   SemiSpace* old_cache = NULL; | 
| 316   { | 311   { | 
| 317     MutexLocker locker(mutex_); | 312     MutexLocker locker(mutex_); | 
| 318     old_cache = cache_; | 313     old_cache = cache_; | 
| 319     cache_ = this; | 314     cache_ = this; | 
| 320   } | 315   } | 
| 321   delete old_cache; | 316   delete old_cache; | 
| 322 } | 317 } | 
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 422     avg_frac /= 1.0 + 0.5;  // Normalize. | 417     avg_frac /= 1.0 + 0.5;  // Normalize. | 
| 423   } | 418   } | 
| 424   if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { | 419   if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { | 
| 425     // Remember the limit to which objects have been copied. | 420     // Remember the limit to which objects have been copied. | 
| 426     survivor_end_ = top_; | 421     survivor_end_ = top_; | 
| 427   } else { | 422   } else { | 
| 428     // Move survivor end to the end of the to_ space, making all surviving | 423     // Move survivor end to the end of the to_ space, making all surviving | 
| 429     // objects candidates for promotion next time. | 424     // objects candidates for promotion next time. | 
| 430     survivor_end_ = end_; | 425     survivor_end_ = end_; | 
| 431   } | 426   } | 
| 432   VerifiedMemory::Accept(to_->start(), to_->end() - to_->start()); |  | 
| 433 #if defined(DEBUG) | 427 #if defined(DEBUG) | 
| 434   // We can only safely verify the store buffers from old space if there is no | 428   // We can only safely verify the store buffers from old space if there is no | 
| 435   // concurrent old space task. At the same time we prevent new tasks from | 429   // concurrent old space task. At the same time we prevent new tasks from | 
| 436   // being spawned. | 430   // being spawned. | 
| 437   { | 431   { | 
| 438     PageSpace* page_space = heap_->old_space(); | 432     PageSpace* page_space = heap_->old_space(); | 
| 439     MonitorLocker ml(page_space->tasks_lock()); | 433     MonitorLocker ml(page_space->tasks_lock()); | 
| 440     if (page_space->tasks() == 0) { | 434     if (page_space->tasks() == 0) { | 
| 441       VerifyStoreBufferPointerVisitor verify_store_buffer_visitor(isolate, to_); | 435       VerifyStoreBufferPointerVisitor verify_store_buffer_visitor(isolate, to_); | 
| 442       heap_->old_space()->VisitObjectPointers(&verify_store_buffer_visitor); | 436       heap_->old_space()->VisitObjectPointers(&verify_store_buffer_visitor); | 
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 899 } | 893 } | 
| 900 | 894 | 
| 901 | 895 | 
| 902 void Scavenger::FreeExternal(intptr_t size) { | 896 void Scavenger::FreeExternal(intptr_t size) { | 
| 903   ASSERT(size >= 0); | 897   ASSERT(size >= 0); | 
| 904   external_size_ -= size; | 898   external_size_ -= size; | 
| 905   ASSERT(external_size_ >= 0); | 899   ASSERT(external_size_ >= 0); | 
| 906 } | 900 } | 
| 907 | 901 | 
| 908 }  // namespace dart | 902 }  // namespace dart | 
| OLD | NEW | 
|---|