Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(522)

Side by Side Diff: runtime/vm/heap.cc

Issue 2609643002: 1. Avoid potential dead lock due to lock-order-inversion (Closed)
Patch Set: Address code review changes. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/heap.h ('k') | runtime/vm/pages.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/heap.h ('k') | runtime/vm/pages.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698