| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/heap.h" | 5 #include "vm/heap.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 uword Heap::AllocateOld(intptr_t size, HeapPage::PageType type) { | 80 uword Heap::AllocateOld(intptr_t size, HeapPage::PageType type) { |
| 81 ASSERT(Thread::Current()->no_safepoint_scope_depth() == 0); | 81 ASSERT(Thread::Current()->no_safepoint_scope_depth() == 0); |
| 82 uword addr = old_space_.TryAllocate(size, type); | 82 uword addr = old_space_.TryAllocate(size, type); |
| 83 if (addr != 0) { | 83 if (addr != 0) { |
| 84 return addr; | 84 return addr; |
| 85 } | 85 } |
| 86 // If we are in the process of running a sweep, wait for the sweeper to free | 86 // If we are in the process of running a sweep, wait for the sweeper to free |
| 87 // memory. | 87 // memory. |
| 88 Thread* thread = Thread::Current(); | 88 Thread* thread = Thread::Current(); |
| 89 if (thread->CanCollectGarbage()) { | 89 if (thread->CanCollectGarbage()) { |
| 90 { | 90 // Wait for any GC tasks that are in progress. |
| 91 MonitorLocker ml(old_space_.tasks_lock()); | 91 WaitForSweeperTasks(thread); |
| 92 addr = old_space_.TryAllocate(size, type); | 92 addr = old_space_.TryAllocate(size, type); |
| 93 while ((addr == 0) && (old_space_.tasks() > 0)) { | |
| 94 ml.WaitWithSafepointCheck(thread); | |
| 95 addr = old_space_.TryAllocate(size, type); | |
| 96 } | |
| 97 } | |
| 98 if (addr != 0) { | 93 if (addr != 0) { |
| 99 return addr; | 94 return addr; |
| 100 } | 95 } |
| 101 // All GC tasks finished without allocating successfully. Run a full GC. | 96 // All GC tasks finished without allocating successfully. Run a full GC. |
| 102 CollectAllGarbage(); | 97 CollectAllGarbage(); |
| 103 addr = old_space_.TryAllocate(size, type); | 98 addr = old_space_.TryAllocate(size, type); |
| 104 if (addr != 0) { | 99 if (addr != 0) { |
| 105 return addr; | 100 return addr; |
| 106 } | 101 } |
| 107 // Wait for all of the concurrent tasks to finish before giving up. | 102 // Wait for all of the concurrent tasks to finish before giving up. |
| 108 { | 103 WaitForSweeperTasks(thread); |
| 109 MonitorLocker ml(old_space_.tasks_lock()); | 104 addr = old_space_.TryAllocate(size, type); |
| 110 addr = old_space_.TryAllocate(size, type); | |
| 111 while ((addr == 0) && (old_space_.tasks() > 0)) { | |
| 112 ml.WaitWithSafepointCheck(thread); | |
| 113 addr = old_space_.TryAllocate(size, type); | |
| 114 } | |
| 115 } | |
| 116 if (addr != 0) { | 105 if (addr != 0) { |
| 117 return addr; | 106 return addr; |
| 118 } | 107 } |
| 119 // Force growth before attempting another synchronous GC. | 108 // Force growth before attempting another synchronous GC. |
| 120 addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth); | 109 addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth); |
| 121 if (addr != 0) { | 110 if (addr != 0) { |
| 122 return addr; | 111 return addr; |
| 123 } | 112 } |
| 124 // Before throwing an out-of-memory error try a synchronous GC. | 113 // Before throwing an out-of-memory error try a synchronous GC. |
| 125 CollectAllGarbage(); | 114 CollectAllGarbage(); |
| 126 { | 115 WaitForSweeperTasks(thread); |
| 127 MonitorLocker ml(old_space_.tasks_lock()); | |
| 128 while (old_space_.tasks() > 0) { | |
| 129 ml.WaitWithSafepointCheck(thread); | |
| 130 } | |
| 131 } | |
| 132 } | 116 } |
| 133 addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth); | 117 addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth); |
| 134 if (addr != 0) { | 118 if (addr != 0) { |
| 135 return addr; | 119 return addr; |
| 136 } | 120 } |
| 137 // Give up allocating this object. | 121 // Give up allocating this object. |
| 138 OS::PrintErr("Exhausted heap space, trying to allocate %" Pd " bytes.\n", | 122 OS::PrintErr("Exhausted heap space, trying to allocate %" Pd " bytes.\n", |
| 139 size); | 123 size); |
| 140 return 0; | 124 return 0; |
| 141 } | 125 } |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 } | 422 } |
| 439 | 423 |
| 440 | 424 |
| 441 void Heap::CollectAllGarbage() { | 425 void Heap::CollectAllGarbage() { |
| 442 Thread* thread = Thread::Current(); | 426 Thread* thread = Thread::Current(); |
| 443 CollectNewSpaceGarbage(thread, kInvokeApiCallbacks, kFull); | 427 CollectNewSpaceGarbage(thread, kInvokeApiCallbacks, kFull); |
| 444 CollectOldSpaceGarbage(thread, kInvokeApiCallbacks, kFull); | 428 CollectOldSpaceGarbage(thread, kInvokeApiCallbacks, kFull); |
| 445 } | 429 } |
| 446 | 430 |
| 447 | 431 |
| 448 #if defined(DEBUG) | 432 void Heap::WaitForSweeperTasks(Thread* thread) { |
| 449 void Heap::WaitForSweeperTasks() { | 433 MonitorLocker ml(old_space_.tasks_lock()); |
| 450 Thread* thread = Thread::Current(); | 434 while (old_space_.tasks() > 0) { |
| 451 { | 435 ml.WaitWithSafepointCheck(thread); |
| 452 MonitorLocker ml(old_space_.tasks_lock()); | |
| 453 while (old_space_.tasks() > 0) { | |
| 454 ml.WaitWithSafepointCheck(thread); | |
| 455 } | |
| 456 } | 436 } |
| 457 } | 437 } |
| 458 #endif | |
| 459 | 438 |
| 460 | 439 |
| 461 void Heap::UpdateGlobalMaxUsed() { | 440 void Heap::UpdateGlobalMaxUsed() { |
| 462 ASSERT(isolate_ != NULL); | 441 ASSERT(isolate_ != NULL); |
| 463 // We are accessing the used in words count for both new and old space | 442 // We are accessing the used in words count for both new and old space |
| 464 // without synchronizing. The value of this metric is approximate. | 443 // without synchronizing. The value of this metric is approximate. |
| 465 isolate_->GetHeapGlobalUsedMaxMetric()->SetValue( | 444 isolate_->GetHeapGlobalUsedMaxMetric()->SetValue( |
| 466 (UsedInWords(Heap::kNew) * kWordSize) + | 445 (UsedInWords(Heap::kNew) * kWordSize) + |
| 467 (UsedInWords(Heap::kOld) * kWordSize)); | 446 (UsedInWords(Heap::kOld) * kWordSize)); |
| 468 } | 447 } |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 Dart::vm_isolate()->heap()->WriteProtect(false); | 822 Dart::vm_isolate()->heap()->WriteProtect(false); |
| 844 } | 823 } |
| 845 | 824 |
| 846 | 825 |
| 847 WritableVMIsolateScope::~WritableVMIsolateScope() { | 826 WritableVMIsolateScope::~WritableVMIsolateScope() { |
| 848 ASSERT(Dart::vm_isolate()->heap()->UsedInWords(Heap::kNew) == 0); | 827 ASSERT(Dart::vm_isolate()->heap()->UsedInWords(Heap::kNew) == 0); |
| 849 Dart::vm_isolate()->heap()->WriteProtect(true); | 828 Dart::vm_isolate()->heap()->WriteProtect(true); |
| 850 } | 829 } |
| 851 | 830 |
| 852 } // namespace dart | 831 } // namespace dart |
| OLD | NEW |