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

Side by Side Diff: src/heap.cc

Issue 8519002: Start incremental marking on idle notification. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments. Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 max_alive_after_gc_(0), 136 max_alive_after_gc_(0),
137 min_in_mutator_(kMaxInt), 137 min_in_mutator_(kMaxInt),
138 alive_after_last_gc_(0), 138 alive_after_last_gc_(0),
139 last_gc_end_timestamp_(0.0), 139 last_gc_end_timestamp_(0.0),
140 store_buffer_(this), 140 store_buffer_(this),
141 marking_(this), 141 marking_(this),
142 incremental_marking_(this), 142 incremental_marking_(this),
143 number_idle_notifications_(0), 143 number_idle_notifications_(0),
144 last_idle_notification_gc_count_(0), 144 last_idle_notification_gc_count_(0),
145 last_idle_notification_gc_count_init_(false), 145 last_idle_notification_gc_count_init_(false),
146 idle_notification_will_schedule_next_gc_(false),
147 mark_sweeps_since_idle_round_started_(0),
148 ms_count_at_last_idle_notification_(0),
149 gc_count_at_last_idle_gc_(0),
150 gc_count_when_last_idle_round_finished_(0),
146 configured_(false), 151 configured_(false),
147 chunks_queued_for_free_(NULL) { 152 chunks_queued_for_free_(NULL) {
148 // Allow build-time customization of the max semispace size. Building 153 // Allow build-time customization of the max semispace size. Building
149 // V8 with snapshots and a non-default max semispace size is much 154 // V8 with snapshots and a non-default max semispace size is much
150 // easier if you can define it as part of the build environment. 155 // easier if you can define it as part of the build environment.
151 #if defined(V8_MAX_SEMISPACE_SIZE) 156 #if defined(V8_MAX_SEMISPACE_SIZE)
152 max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; 157 max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE;
153 #endif 158 #endif
154 159
155 intptr_t max_virtual = OS::MaxVirtualMemory(); 160 intptr_t max_virtual = OS::MaxVirtualMemory();
(...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 1008
1004 // Used for updating survived_since_last_expansion_ at function end. 1009 // Used for updating survived_since_last_expansion_ at function end.
1005 intptr_t survived_watermark = PromotedSpaceSize(); 1010 intptr_t survived_watermark = PromotedSpaceSize();
1006 1011
1007 CheckNewSpaceExpansionCriteria(); 1012 CheckNewSpaceExpansionCriteria();
1008 1013
1009 SelectScavengingVisitorsTable(); 1014 SelectScavengingVisitorsTable();
1010 1015
1011 incremental_marking()->PrepareForScavenge(); 1016 incremental_marking()->PrepareForScavenge();
1012 1017
1013 old_pointer_space()->AdvanceSweeper(new_space_.Size()); 1018 AdvanceSweepers(new_space_.Size());
1014 old_data_space()->AdvanceSweeper(new_space_.Size());
1015 1019
1016 // Flip the semispaces. After flipping, to space is empty, from space has 1020 // Flip the semispaces. After flipping, to space is empty, from space has
1017 // live objects. 1021 // live objects.
1018 new_space_.Flip(); 1022 new_space_.Flip();
1019 new_space_.ResetAllocationInfo(); 1023 new_space_.ResetAllocationInfo();
1020 1024
1021 // We need to sweep newly copied objects which can be either in the 1025 // We need to sweep newly copied objects which can be either in the
1022 // to space or promoted to the old generation. For to-space 1026 // to space or promoted to the old generation. For to-space
1023 // objects, we treat the bottom of the to space as a queue. Newly 1027 // objects, we treat the bottom of the to space as a queue. Newly
1024 // copied and unswept objects lie between a 'front' mark and the 1028 // copied and unswept objects lie between a 'front' mark and the
(...skipping 3428 matching lines...) Expand 10 before | Expand all | Expand 10 after
4453 4457
4454 void Heap::EnsureHeapIsIterable() { 4458 void Heap::EnsureHeapIsIterable() {
4455 ASSERT(IsAllocationAllowed()); 4459 ASSERT(IsAllocationAllowed());
4456 if (!IsHeapIterable()) { 4460 if (!IsHeapIterable()) {
4457 CollectAllGarbage(kMakeHeapIterableMask); 4461 CollectAllGarbage(kMakeHeapIterableMask);
4458 } 4462 }
4459 ASSERT(IsHeapIterable()); 4463 ASSERT(IsHeapIterable());
4460 } 4464 }
4461 4465
4462 4466
4463 bool Heap::IdleNotification() { 4467 bool Heap::IdleNotification(int hint) {
4468 if (!FLAG_incremental_marking) {
4469 return hint < 1000 ? true : IdleGlobalGC();
4470 }
4471
4472 // By doing small chunks of GC work in each IdleNotification,
4473 // perform a round of incremental GCs and after that wait until
4474 // the mutator creates enough garbage to justify a new round.
4475 // An incremental GC progresses as follows:
4476 // 1. many incremental marking steps,
4477 // 2. one old space mark-sweep-compact,
4478 // 3. many lazy sweep steps.
4479 // Use mark-sweep-compact events to count incremental GCs in a round.
4480
4481 if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
4482 if (EnoughGarbageSinceLastIdleRound()) {
4483 StartIdleRound();
4484 } else {
4485 return true;
4486 }
4487 }
4488
4489 int new_mark_sweeps = ms_count_ - ms_count_at_last_idle_notification_;
4490 mark_sweeps_since_idle_round_started_ += new_mark_sweeps;
4491 ms_count_at_last_idle_notification_ = ms_count_;
4492
4493 if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
4494 FinishIdleRound();
4495 return true;
4496 }
4497
4498 intptr_t size_factor = Min(Max(hint, 30), 1000) / 10;
4499 // The size factor is in range [3..100].
4500 intptr_t step_size = size_factor * IncrementalMarking::kAllocatedThreshold;
4501
4502 if (incremental_marking()->IsStopped()) {
4503 if (!IsSweepingComplete() && !AdvanceSweepers(step_size)) {
4504 return false;
4505 }
4506 if (!WorthStartingGCWhenIdle()) {
4507 FinishIdleRound();
4508 return true;
4509 }
4510 incremental_marking()->Start();
4511 }
4512
4513 // This flag prevents incremental marking from requesting GC via stack guard
4514 idle_notification_will_schedule_next_gc_ = true;
4515 incremental_marking()->Step(step_size);
4516 idle_notification_will_schedule_next_gc_ = false;
4517
4518 if (incremental_marking()->IsComplete()) {
4519 bool uncommit = false;
4520 if (gc_count_at_last_idle_gc_ == gc_count_) {
4521 isolate_->compilation_cache()->Clear();
4522 uncommit = true;
4523 }
4524 CollectAllGarbage(kNoGCFlags);
4525 gc_count_at_last_idle_gc_ = gc_count_;
4526 if (uncommit) {
4527 new_space_.Shrink();
4528 UncommitFromSpace();
4529 }
4530 }
4531 return false;
4532 }
4533
4534
4535 bool Heap::IdleGlobalGC() {
4464 static const int kIdlesBeforeScavenge = 4; 4536 static const int kIdlesBeforeScavenge = 4;
4465 static const int kIdlesBeforeMarkSweep = 7; 4537 static const int kIdlesBeforeMarkSweep = 7;
4466 static const int kIdlesBeforeMarkCompact = 8; 4538 static const int kIdlesBeforeMarkCompact = 8;
4467 static const int kMaxIdleCount = kIdlesBeforeMarkCompact + 1; 4539 static const int kMaxIdleCount = kIdlesBeforeMarkCompact + 1;
4468 static const unsigned int kGCsBetweenCleanup = 4; 4540 static const unsigned int kGCsBetweenCleanup = 4;
4469 4541
4470 if (!last_idle_notification_gc_count_init_) { 4542 if (!last_idle_notification_gc_count_init_) {
4471 last_idle_notification_gc_count_ = gc_count_; 4543 last_idle_notification_gc_count_ = gc_count_;
4472 last_idle_notification_gc_count_init_ = true; 4544 last_idle_notification_gc_count_init_ = true;
4473 } 4545 }
(...skipping 1939 matching lines...) Expand 10 before | Expand all | Expand 10 after
6413 isolate_->heap()->store_buffer()->Compact(); 6485 isolate_->heap()->store_buffer()->Compact();
6414 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); 6486 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED);
6415 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { 6487 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) {
6416 next = chunk->next_chunk(); 6488 next = chunk->next_chunk();
6417 isolate_->memory_allocator()->Free(chunk); 6489 isolate_->memory_allocator()->Free(chunk);
6418 } 6490 }
6419 chunks_queued_for_free_ = NULL; 6491 chunks_queued_for_free_ = NULL;
6420 } 6492 }
6421 6493
6422 } } // namespace v8::internal 6494 } } // namespace v8::internal
OLDNEW
« src/heap.h ('K') | « src/heap.h ('k') | src/incremental-marking.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698