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 |