OLD | NEW |
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 2227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2238 Code* code = it.frame()->LookupCode(); | 2238 Code* code = it.frame()->LookupCode(); |
2239 if (!code->CanDeoptAt(it.frame()->pc())) { | 2239 if (!code->CanDeoptAt(it.frame()->pc())) { |
2240 Code::BodyDescriptor::IterateBody(code, visitor); | 2240 Code::BodyDescriptor::IterateBody(code, visitor); |
2241 } | 2241 } |
2242 ProcessMarkingDeque(); | 2242 ProcessMarkingDeque(); |
2243 return; | 2243 return; |
2244 } | 2244 } |
2245 } | 2245 } |
2246 } | 2246 } |
2247 | 2247 |
2248 void MarkingDeque::SetUp() { | |
2249 backing_store_ = new base::VirtualMemory(kMaxSize); | |
2250 backing_store_committed_size_ = 0; | |
2251 if (backing_store_ == nullptr) { | |
2252 V8::FatalProcessOutOfMemory("MarkingDeque::SetUp"); | |
2253 } | |
2254 } | |
2255 | |
2256 void MarkingDeque::TearDown() { | |
2257 delete backing_store_; | |
2258 } | |
2259 | |
2260 void MarkingDeque::StartUsing() { | |
2261 base::LockGuard<base::Mutex> guard(&mutex_); | |
2262 if (in_use_) { | |
2263 // This can happen in mark-compact GC if the incremental marker already | |
2264 // started using the marking deque. | |
2265 return; | |
2266 } | |
2267 in_use_ = true; | |
2268 EnsureCommitted(); | |
2269 array_ = reinterpret_cast<HeapObject**>(backing_store_->address()); | |
2270 size_t size = FLAG_force_marking_deque_overflows | |
2271 ? 64 * kPointerSize | |
2272 : backing_store_committed_size_; | |
2273 DCHECK( | |
2274 base::bits::IsPowerOfTwo32(static_cast<uint32_t>(size / kPointerSize))); | |
2275 mask_ = static_cast<int>((size / kPointerSize) - 1); | |
2276 top_ = bottom_ = 0; | |
2277 overflowed_ = false; | |
2278 } | |
2279 | |
2280 void MarkingDeque::StopUsing() { | |
2281 base::LockGuard<base::Mutex> guard(&mutex_); | |
2282 if (!in_use_) return; | |
2283 DCHECK(IsEmpty()); | |
2284 DCHECK(!overflowed_); | |
2285 top_ = bottom_ = mask_ = 0; | |
2286 in_use_ = false; | |
2287 if (FLAG_concurrent_sweeping) { | |
2288 StartUncommitTask(); | |
2289 } else { | |
2290 Uncommit(); | |
2291 } | |
2292 } | |
2293 | |
2294 void MarkingDeque::Clear() { | |
2295 DCHECK(in_use_); | |
2296 top_ = bottom_ = 0; | |
2297 overflowed_ = false; | |
2298 } | |
2299 | |
2300 void MarkingDeque::Uncommit() { | |
2301 DCHECK(!in_use_); | |
2302 bool success = backing_store_->Uncommit(backing_store_->address(), | |
2303 backing_store_committed_size_); | |
2304 backing_store_committed_size_ = 0; | |
2305 CHECK(success); | |
2306 } | |
2307 | |
2308 void MarkingDeque::EnsureCommitted() { | |
2309 DCHECK(in_use_); | |
2310 if (backing_store_committed_size_ > 0) return; | |
2311 | |
2312 for (size_t size = kMaxSize; size >= kMinSize; size /= 2) { | |
2313 if (backing_store_->Commit(backing_store_->address(), size, false)) { | |
2314 backing_store_committed_size_ = size; | |
2315 break; | |
2316 } | |
2317 } | |
2318 if (backing_store_committed_size_ == 0) { | |
2319 V8::FatalProcessOutOfMemory("MarkingDeque::EnsureCommitted"); | |
2320 } | |
2321 } | |
2322 | |
2323 void MarkingDeque::StartUncommitTask() { | |
2324 if (!uncommit_task_pending_) { | |
2325 uncommit_task_pending_ = true; | |
2326 UncommitTask* task = new UncommitTask(heap_->isolate(), this); | |
2327 V8::GetCurrentPlatform()->CallOnBackgroundThread( | |
2328 task, v8::Platform::kShortRunningTask); | |
2329 } | |
2330 } | |
2331 | |
2332 class ObjectStatsVisitor : public HeapObjectVisitor { | 2248 class ObjectStatsVisitor : public HeapObjectVisitor { |
2333 public: | 2249 public: |
2334 ObjectStatsVisitor(Heap* heap, ObjectStats* live_stats, | 2250 ObjectStatsVisitor(Heap* heap, ObjectStats* live_stats, |
2335 ObjectStats* dead_stats) | 2251 ObjectStats* dead_stats) |
2336 : live_collector_(heap, live_stats), dead_collector_(heap, dead_stats) { | 2252 : live_collector_(heap, live_stats), dead_collector_(heap, dead_stats) { |
2337 DCHECK_NOT_NULL(live_stats); | 2253 DCHECK_NOT_NULL(live_stats); |
2338 DCHECK_NOT_NULL(dead_stats); | 2254 DCHECK_NOT_NULL(dead_stats); |
2339 // Global objects are roots and thus recorded as live. | 2255 // Global objects are roots and thus recorded as live. |
2340 live_collector_.CollectGlobalStatistics(); | 2256 live_collector_.CollectGlobalStatistics(); |
2341 } | 2257 } |
(...skipping 1872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4214 // The target is always in old space, we don't have to record the slot in | 4130 // The target is always in old space, we don't have to record the slot in |
4215 // the old-to-new remembered set. | 4131 // the old-to-new remembered set. |
4216 DCHECK(!heap()->InNewSpace(target)); | 4132 DCHECK(!heap()->InNewSpace(target)); |
4217 RecordRelocSlot(host, &rinfo, target); | 4133 RecordRelocSlot(host, &rinfo, target); |
4218 } | 4134 } |
4219 } | 4135 } |
4220 } | 4136 } |
4221 | 4137 |
4222 } // namespace internal | 4138 } // namespace internal |
4223 } // namespace v8 | 4139 } // namespace v8 |
OLD | NEW |