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 |
11 #include "vm/dart.h" | 11 #include "vm/dart.h" |
12 #include "vm/dart_api_state.h" | 12 #include "vm/dart_api_state.h" |
13 #include "vm/isolate.h" | 13 #include "vm/isolate.h" |
14 #include "vm/lockers.h" | 14 #include "vm/lockers.h" |
15 #include "vm/object.h" | 15 #include "vm/object.h" |
16 #include "vm/object_id_ring.h" | 16 #include "vm/object_id_ring.h" |
17 #include "vm/stack_frame.h" | 17 #include "vm/stack_frame.h" |
18 #include "vm/store_buffer.h" | 18 #include "vm/store_buffer.h" |
| 19 #include "vm/verified_memory.h" |
19 #include "vm/verifier.h" | 20 #include "vm/verifier.h" |
20 #include "vm/visitor.h" | 21 #include "vm/visitor.h" |
21 #include "vm/weak_table.h" | 22 #include "vm/weak_table.h" |
22 | 23 |
23 namespace dart { | 24 namespace dart { |
24 | 25 |
25 DEFINE_FLAG(int, early_tenuring_threshold, 66, | 26 DEFINE_FLAG(int, early_tenuring_threshold, 66, |
26 "When more than this percentage of promotion candidates survive, " | 27 "When more than this percentage of promotion candidates survive, " |
27 "promote all survivors of next scavenge."); | 28 "promote all survivors of next scavenge."); |
28 DEFINE_FLAG(int, new_gen_garbage_threshold, 90, | 29 DEFINE_FLAG(int, new_gen_garbage_threshold, 90, |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 class_table->UpdateLiveNew(cid, size); | 221 class_table->UpdateLiveNew(cid, size); |
221 } | 222 } |
222 } | 223 } |
223 // During a scavenge we always succeed to at least copy all of the | 224 // During a scavenge we always succeed to at least copy all of the |
224 // current objects to the to space. | 225 // current objects to the to space. |
225 ASSERT(new_addr != 0); | 226 ASSERT(new_addr != 0); |
226 // Copy the object to the new location. | 227 // Copy the object to the new location. |
227 memmove(reinterpret_cast<void*>(new_addr), | 228 memmove(reinterpret_cast<void*>(new_addr), |
228 reinterpret_cast<void*>(raw_addr), | 229 reinterpret_cast<void*>(raw_addr), |
229 size); | 230 size); |
| 231 VerifiedMemory::Accept(new_addr, size); |
230 // Remember forwarding address. | 232 // Remember forwarding address. |
231 ForwardTo(raw_addr, new_addr); | 233 ForwardTo(raw_addr, new_addr); |
232 } | 234 } |
233 // Update the reference. | 235 // Update the reference. |
234 RawObject* new_obj = RawObject::FromAddr(new_addr); | 236 RawObject* new_obj = RawObject::FromAddr(new_addr); |
235 *p = new_obj; | 237 *p = new_obj; |
236 // Update the store buffer as needed. | 238 // Update the store buffer as needed. |
237 if (visiting_old_object_ != NULL) { | 239 if (visiting_old_object_ != NULL) { |
| 240 VerifiedMemory::Accept(reinterpret_cast<uword>(p), sizeof(*p)); |
238 UpdateStoreBuffer(p, new_obj); | 241 UpdateStoreBuffer(p, new_obj); |
239 } | 242 } |
240 } | 243 } |
241 | 244 |
242 Scavenger* scavenger_; | 245 Scavenger* scavenger_; |
243 uword from_start_; | 246 uword from_start_; |
244 uword from_size_; | 247 uword from_size_; |
245 Heap* heap_; | 248 Heap* heap_; |
246 Heap* vm_heap_; | 249 Heap* vm_heap_; |
247 PageSpace* page_space_; | 250 PageSpace* page_space_; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 if (cache_ != NULL && cache_->size_in_words() == size_in_words) { | 352 if (cache_ != NULL && cache_->size_in_words() == size_in_words) { |
350 SemiSpace* result = cache_; | 353 SemiSpace* result = cache_; |
351 cache_ = NULL; | 354 cache_ = NULL; |
352 return result; | 355 return result; |
353 } | 356 } |
354 } | 357 } |
355 if (size_in_words == 0) { | 358 if (size_in_words == 0) { |
356 return new SemiSpace(NULL); | 359 return new SemiSpace(NULL); |
357 } else { | 360 } else { |
358 intptr_t size_in_bytes = size_in_words << kWordSizeLog2; | 361 intptr_t size_in_bytes = size_in_words << kWordSizeLog2; |
359 VirtualMemory* reserved = VirtualMemory::Reserve(size_in_bytes); | 362 VirtualMemory* reserved = VerifiedMemory::Reserve(size_in_bytes); |
360 if ((reserved == NULL) || !reserved->Commit(false)) { // Not executable. | 363 if ((reserved == NULL) || !reserved->Commit(false)) { // Not executable. |
361 // TODO(koda): If cache_ is not empty, we could try to delete it. | 364 // TODO(koda): If cache_ is not empty, we could try to delete it. |
362 delete reserved; | 365 delete reserved; |
363 return NULL; | 366 return NULL; |
364 } | 367 } |
365 #if defined(DEBUG) | 368 #if defined(DEBUG) |
366 memset(reserved->address(), kZapValue, size_in_bytes); | 369 memset(reserved->address(), kZapValue, size_in_bytes); |
367 #endif // defined(DEBUG) | 370 #endif // defined(DEBUG) |
368 return new SemiSpace(reserved); | 371 return new SemiSpace(reserved); |
369 } | 372 } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 avg_frac /= 1.0 + 0.5; // Normalize. | 482 avg_frac /= 1.0 + 0.5; // Normalize. |
480 } | 483 } |
481 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { | 484 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { |
482 // Remember the limit to which objects have been copied. | 485 // Remember the limit to which objects have been copied. |
483 survivor_end_ = top_; | 486 survivor_end_ = top_; |
484 } else { | 487 } else { |
485 // Move survivor end to the end of the to_ space, making all surviving | 488 // Move survivor end to the end of the to_ space, making all surviving |
486 // objects candidates for promotion next time. | 489 // objects candidates for promotion next time. |
487 survivor_end_ = end_; | 490 survivor_end_ = end_; |
488 } | 491 } |
489 | 492 VerifiedMemory::Accept(to_->start(), to_->end() - to_->start()); |
490 #if defined(DEBUG) | 493 #if defined(DEBUG) |
491 // We can only safely verify the store buffers from old space if there is no | 494 // We can only safely verify the store buffers from old space if there is no |
492 // concurrent old space task. At the same time we prevent new tasks from | 495 // concurrent old space task. At the same time we prevent new tasks from |
493 // being spawned. | 496 // being spawned. |
494 { | 497 { |
495 PageSpace* page_space = heap_->old_space(); | 498 PageSpace* page_space = heap_->old_space(); |
496 MonitorLocker ml(page_space->tasks_lock()); | 499 MonitorLocker ml(page_space->tasks_lock()); |
497 if (page_space->tasks() == 0) { | 500 if (page_space->tasks() == 0) { |
498 VerifyStoreBufferPointerVisitor verify_store_buffer_visitor(isolate, to_); | 501 VerifyStoreBufferPointerVisitor verify_store_buffer_visitor(isolate, to_); |
499 heap_->IterateOldPointers(&verify_store_buffer_visitor); | 502 heap_->IterateOldPointers(&verify_store_buffer_visitor); |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 } | 893 } |
891 | 894 |
892 | 895 |
893 void Scavenger::FreeExternal(intptr_t size) { | 896 void Scavenger::FreeExternal(intptr_t size) { |
894 ASSERT(size >= 0); | 897 ASSERT(size >= 0); |
895 external_size_ -= size; | 898 external_size_ -= size; |
896 ASSERT(external_size_ >= 0); | 899 ASSERT(external_size_ >= 0); |
897 } | 900 } |
898 | 901 |
899 } // namespace dart | 902 } // namespace dart |
OLD | NEW |