| 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 |