Chromium Code Reviews

Side by Side Diff: src/heap/mark-compact.cc

Issue 2810893002: [heap] Implement simple concurrent marking deque. (Closed)
Patch Set: revert flags Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/heap/mark-compact.h" 5 #include "src/heap/mark-compact.h"
6 6
7 #include "src/base/atomicops.h" 7 #include "src/base/atomicops.h"
8 #include "src/base/bits.h" 8 #include "src/base/bits.h"
9 #include "src/base/sys-info.h" 9 #include "src/base/sys-info.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 2217 matching lines...)
2228 Code* code = it.frame()->LookupCode(); 2228 Code* code = it.frame()->LookupCode();
2229 if (!code->CanDeoptAt(it.frame()->pc())) { 2229 if (!code->CanDeoptAt(it.frame()->pc())) {
2230 Code::BodyDescriptor::IterateBody(code, visitor); 2230 Code::BodyDescriptor::IterateBody(code, visitor);
2231 } 2231 }
2232 ProcessMarkingDeque(); 2232 ProcessMarkingDeque();
2233 return; 2233 return;
2234 } 2234 }
2235 } 2235 }
2236 } 2236 }
2237 2237
2238 void MarkingDeque::SetUp() {
ulan 2017/04/27 17:49:39 This is moved to sequential-marking-deque.cc
2239 backing_store_ = new base::VirtualMemory(kMaxSize);
2240 backing_store_committed_size_ = 0;
2241 if (backing_store_ == nullptr) {
2242 V8::FatalProcessOutOfMemory("MarkingDeque::SetUp");
2243 }
2244 }
2245
2246 void MarkingDeque::TearDown() {
2247 delete backing_store_;
2248 }
2249
2250 void MarkingDeque::StartUsing() {
2251 base::LockGuard<base::Mutex> guard(&mutex_);
2252 if (in_use_) {
2253 // This can happen in mark-compact GC if the incremental marker already
2254 // started using the marking deque.
2255 return;
2256 }
2257 in_use_ = true;
2258 EnsureCommitted();
2259 array_ = reinterpret_cast<HeapObject**>(backing_store_->address());
2260 size_t size = FLAG_force_marking_deque_overflows
2261 ? 64 * kPointerSize
2262 : backing_store_committed_size_;
2263 DCHECK(
2264 base::bits::IsPowerOfTwo32(static_cast<uint32_t>(size / kPointerSize)));
2265 mask_ = static_cast<int>((size / kPointerSize) - 1);
2266 top_ = bottom_ = 0;
2267 overflowed_ = false;
2268 }
2269
2270 void MarkingDeque::StopUsing() {
2271 base::LockGuard<base::Mutex> guard(&mutex_);
2272 if (!in_use_) return;
2273 DCHECK(IsEmpty());
2274 DCHECK(!overflowed_);
2275 top_ = bottom_ = mask_ = 0;
2276 in_use_ = false;
2277 if (FLAG_concurrent_sweeping) {
2278 StartUncommitTask();
2279 } else {
2280 Uncommit();
2281 }
2282 }
2283
2284 void MarkingDeque::Clear() {
2285 DCHECK(in_use_);
2286 top_ = bottom_ = 0;
2287 overflowed_ = false;
2288 }
2289
2290 void MarkingDeque::Uncommit() {
2291 DCHECK(!in_use_);
2292 bool success = backing_store_->Uncommit(backing_store_->address(),
2293 backing_store_committed_size_);
2294 backing_store_committed_size_ = 0;
2295 CHECK(success);
2296 }
2297
2298 void MarkingDeque::EnsureCommitted() {
2299 DCHECK(in_use_);
2300 if (backing_store_committed_size_ > 0) return;
2301
2302 for (size_t size = kMaxSize; size >= kMinSize; size /= 2) {
2303 if (backing_store_->Commit(backing_store_->address(), size, false)) {
2304 backing_store_committed_size_ = size;
2305 break;
2306 }
2307 }
2308 if (backing_store_committed_size_ == 0) {
2309 V8::FatalProcessOutOfMemory("MarkingDeque::EnsureCommitted");
2310 }
2311 }
2312
2313 void MarkingDeque::StartUncommitTask() {
2314 if (!uncommit_task_pending_) {
2315 uncommit_task_pending_ = true;
2316 UncommitTask* task = new UncommitTask(heap_->isolate(), this);
2317 V8::GetCurrentPlatform()->CallOnBackgroundThread(
2318 task, v8::Platform::kShortRunningTask);
2319 }
2320 }
2321
2322 class ObjectStatsVisitor : public HeapObjectVisitor { 2238 class ObjectStatsVisitor : public HeapObjectVisitor {
2323 public: 2239 public:
2324 ObjectStatsVisitor(Heap* heap, ObjectStats* live_stats, 2240 ObjectStatsVisitor(Heap* heap, ObjectStats* live_stats,
2325 ObjectStats* dead_stats) 2241 ObjectStats* dead_stats)
2326 : live_collector_(heap, live_stats), dead_collector_(heap, dead_stats) { 2242 : live_collector_(heap, live_stats), dead_collector_(heap, dead_stats) {
2327 DCHECK_NOT_NULL(live_stats); 2243 DCHECK_NOT_NULL(live_stats);
2328 DCHECK_NOT_NULL(dead_stats); 2244 DCHECK_NOT_NULL(dead_stats);
2329 // Global objects are roots and thus recorded as live. 2245 // Global objects are roots and thus recorded as live.
2330 live_collector_.CollectGlobalStatistics(); 2246 live_collector_.CollectGlobalStatistics();
2331 } 2247 }
(...skipping 1869 matching lines...)
4201 // The target is always in old space, we don't have to record the slot in 4117 // The target is always in old space, we don't have to record the slot in
4202 // the old-to-new remembered set. 4118 // the old-to-new remembered set.
4203 DCHECK(!heap()->InNewSpace(target)); 4119 DCHECK(!heap()->InNewSpace(target));
4204 RecordRelocSlot(host, &rinfo, target); 4120 RecordRelocSlot(host, &rinfo, target);
4205 } 4121 }
4206 } 4122 }
4207 } 4123 }
4208 4124
4209 } // namespace internal 4125 } // namespace internal
4210 } // namespace v8 4126 } // namespace v8
OLDNEW

Powered by Google App Engine