| 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 |