| OLD | NEW |
| 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 INLINE(void MarkObjectByPointer(Object** p)) { | 80 INLINE(void MarkObjectByPointer(Object** p)) { |
| 81 Object* obj = *p; | 81 Object* obj = *p; |
| 82 // Since we can be sure that the object is not tagged as a failure we can | 82 // Since we can be sure that the object is not tagged as a failure we can |
| 83 // inline a slightly more efficient tag check here than IsHeapObject() would | 83 // inline a slightly more efficient tag check here than IsHeapObject() would |
| 84 // produce. | 84 // produce. |
| 85 if (obj->NonFailureIsHeapObject()) { | 85 if (obj->NonFailureIsHeapObject()) { |
| 86 HeapObject* heap_object = HeapObject::cast(obj); | 86 HeapObject* heap_object = HeapObject::cast(obj); |
| 87 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); | 87 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); |
| 88 if (mark_bit.data_only()) { | 88 if (mark_bit.data_only()) { |
| 89 incremental_marking_->MarkBlackOrKeepGrey(mark_bit); | 89 incremental_marking_->MarkBlackOrKeepGrey(mark_bit); |
| 90 } else { | 90 } else if (Marking::IsWhite(mark_bit)) { |
| 91 if (Marking::IsWhite(mark_bit)) { | 91 incremental_marking_->WhiteToGreyAndPush(heap_object, mark_bit); |
| 92 incremental_marking_->WhiteToGreyAndPush(heap_object, mark_bit); | |
| 93 } | |
| 94 } | 92 } |
| 95 } | 93 } |
| 96 } | 94 } |
| 97 | 95 |
| 98 Heap* heap_; | 96 Heap* heap_; |
| 99 IncrementalMarking* incremental_marking_; | 97 IncrementalMarking* incremental_marking_; |
| 100 }; | 98 }; |
| 101 | 99 |
| 102 | 100 |
| 103 class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor { | 101 class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 chunk->scan_on_scavenge()) { | 144 chunk->scan_on_scavenge()) { |
| 147 chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); | 145 chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); |
| 148 chunk->ClearFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); | 146 chunk->ClearFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); |
| 149 } else { | 147 } else { |
| 150 chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); | 148 chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); |
| 151 chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); | 149 chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); |
| 152 } | 150 } |
| 153 } | 151 } |
| 154 | 152 |
| 155 | 153 |
| 156 void IncrementalMarking::SetNewSpacePageFlags(MemoryChunk* chunk, | 154 void IncrementalMarking::SetNewSpacePageFlags(NewSpacePage* chunk, |
| 157 bool is_marking) { | 155 bool is_marking) { |
| 158 chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); | 156 chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); |
| 159 if (is_marking) { | 157 if (is_marking) { |
| 160 chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); | 158 chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); |
| 161 } else { | 159 } else { |
| 162 chunk->ClearFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); | 160 chunk->ClearFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); |
| 163 } | 161 } |
| 162 chunk->SetFlag(MemoryChunk::SCAN_ON_SCAVENGE); |
| 164 } | 163 } |
| 165 | 164 |
| 166 | 165 |
| 167 void IncrementalMarking::DeactivateWriteBarrierForSpace(PagedSpace* space) { | 166 void IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace( |
| 167 PagedSpace* space) { |
| 168 PageIterator it(space); | 168 PageIterator it(space); |
| 169 while (it.has_next()) { | 169 while (it.has_next()) { |
| 170 Page* p = it.next(); | 170 Page* p = it.next(); |
| 171 SetOldSpacePageFlags(p, false); | 171 SetOldSpacePageFlags(p, false); |
| 172 } | 172 } |
| 173 } | 173 } |
| 174 | 174 |
| 175 | 175 |
| 176 void IncrementalMarking::DeactivateWriteBarrier() { | 176 void IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace( |
| 177 DeactivateWriteBarrierForSpace(heap_->old_pointer_space()); | 177 NewSpace* space) { |
| 178 DeactivateWriteBarrierForSpace(heap_->old_data_space()); | 178 NewSpacePageIterator it(space); |
| 179 DeactivateWriteBarrierForSpace(heap_->cell_space()); | 179 while (it.has_next()) { |
| 180 DeactivateWriteBarrierForSpace(heap_->map_space()); | 180 NewSpacePage* p = it.next(); |
| 181 DeactivateWriteBarrierForSpace(heap_->code_space()); | 181 SetNewSpacePageFlags(p, false); |
| 182 } |
| 183 } |
| 182 | 184 |
| 183 SetNewSpacePageFlags(heap_->new_space()->ActivePage(), false); | 185 |
| 186 void IncrementalMarking::DeactivateIncrementalWriteBarrier() { |
| 187 DeactivateIncrementalWriteBarrierForSpace(heap_->old_pointer_space()); |
| 188 DeactivateIncrementalWriteBarrierForSpace(heap_->old_data_space()); |
| 189 DeactivateIncrementalWriteBarrierForSpace(heap_->cell_space()); |
| 190 DeactivateIncrementalWriteBarrierForSpace(heap_->map_space()); |
| 191 DeactivateIncrementalWriteBarrierForSpace(heap_->code_space()); |
| 192 DeactivateIncrementalWriteBarrierForSpace(heap_->new_space()); |
| 184 | 193 |
| 185 LargePage* lop = heap_->lo_space()->first_page(); | 194 LargePage* lop = heap_->lo_space()->first_page(); |
| 186 while (lop->is_valid()) { | 195 while (lop->is_valid()) { |
| 187 SetOldSpacePageFlags(lop, false); | 196 SetOldSpacePageFlags(lop, false); |
| 188 lop = lop->next_page(); | 197 lop = lop->next_page(); |
| 189 } | 198 } |
| 190 } | 199 } |
| 191 | 200 |
| 192 | 201 |
| 193 void IncrementalMarking::ClearMarkbits(PagedSpace* space) { | 202 void IncrementalMarking::ClearMarkbits(PagedSpace* space) { |
| 194 PageIterator it(space); | 203 PageIterator it(space); |
| 195 while (it.has_next()) { | 204 while (it.has_next()) { |
| 196 Page* p = it.next(); | 205 Page* p = it.next(); |
| 197 p->markbits()->Clear(); | 206 p->markbits()->Clear(); |
| 198 SetOldSpacePageFlags(p, true); | 207 SetOldSpacePageFlags(p, true); |
| 199 } | 208 } |
| 200 } | 209 } |
| 201 | 210 |
| 202 | 211 |
| 212 void IncrementalMarking::ClearMarkbits(NewSpace* space) { |
| 213 NewSpacePageIterator it(space->ToSpaceLow(), space->ToSpaceHigh()); |
| 214 while (it.has_next()) { |
| 215 NewSpacePage* p = it.next(); |
| 216 p->markbits()->Clear(); |
| 217 SetNewSpacePageFlags(p, true); |
| 218 } |
| 219 } |
| 220 |
| 221 |
| 203 void IncrementalMarking::ClearMarkbits() { | 222 void IncrementalMarking::ClearMarkbits() { |
| 204 // TODO(gc): Clear the mark bits in the sweeper. | 223 // TODO(gc): Clear the mark bits in the sweeper. |
| 205 ClearMarkbits(heap_->old_pointer_space()); | 224 ClearMarkbits(heap_->old_pointer_space()); |
| 206 ClearMarkbits(heap_->old_data_space()); | 225 ClearMarkbits(heap_->old_data_space()); |
| 207 ClearMarkbits(heap_->cell_space()); | 226 ClearMarkbits(heap_->cell_space()); |
| 208 ClearMarkbits(heap_->map_space()); | 227 ClearMarkbits(heap_->map_space()); |
| 209 ClearMarkbits(heap_->code_space()); | 228 ClearMarkbits(heap_->code_space()); |
| 210 heap_->new_space()->ActivePage()->markbits()->Clear(); | 229 ClearMarkbits(heap_->new_space()); |
| 211 | |
| 212 SetNewSpacePageFlags(heap_->new_space()->ActivePage(), true); | |
| 213 | 230 |
| 214 LargePage* lop = heap_->lo_space()->first_page(); | 231 LargePage* lop = heap_->lo_space()->first_page(); |
| 215 while (lop->is_valid()) { | 232 while (lop->is_valid()) { |
| 216 SetOldSpacePageFlags(lop, true); | 233 SetOldSpacePageFlags(lop, true); |
| 217 lop = lop->next_page(); | 234 lop = lop->next_page(); |
| 218 } | 235 } |
| 219 } | 236 } |
| 220 | 237 |
| 221 | 238 |
| 222 #ifdef DEBUG | 239 #ifdef DEBUG |
| 223 void IncrementalMarking::VerifyMarkbitsAreClean(PagedSpace* space) { | 240 void IncrementalMarking::VerifyMarkbitsAreClean(PagedSpace* space) { |
| 224 PageIterator it(space); | 241 PageIterator it(space); |
| 225 | 242 |
| 226 while (it.has_next()) { | 243 while (it.has_next()) { |
| 227 Page* p = it.next(); | 244 Page* p = it.next(); |
| 228 ASSERT(p->markbits()->IsClean()); | 245 ASSERT(p->markbits()->IsClean()); |
| 229 } | 246 } |
| 230 } | 247 } |
| 231 | 248 |
| 232 | 249 |
| 250 void IncrementalMarking::VerifyMarkbitsAreClean(NewSpace* space) { |
| 251 NewSpacePageIterator it(space->ToSpaceLow(), space->ToSpaceHigh()); |
| 252 |
| 253 while (it.has_next()) { |
| 254 NewSpacePage* p = it.next(); |
| 255 ASSERT(p->markbits()->IsClean()); |
| 256 } |
| 257 } |
| 258 |
| 259 |
| 233 void IncrementalMarking::VerifyMarkbitsAreClean() { | 260 void IncrementalMarking::VerifyMarkbitsAreClean() { |
| 234 VerifyMarkbitsAreClean(heap_->old_pointer_space()); | 261 VerifyMarkbitsAreClean(heap_->old_pointer_space()); |
| 235 VerifyMarkbitsAreClean(heap_->old_data_space()); | 262 VerifyMarkbitsAreClean(heap_->old_data_space()); |
| 236 VerifyMarkbitsAreClean(heap_->code_space()); | 263 VerifyMarkbitsAreClean(heap_->code_space()); |
| 237 VerifyMarkbitsAreClean(heap_->cell_space()); | 264 VerifyMarkbitsAreClean(heap_->cell_space()); |
| 238 VerifyMarkbitsAreClean(heap_->map_space()); | 265 VerifyMarkbitsAreClean(heap_->map_space()); |
| 239 ASSERT(heap_->new_space()->ActivePage()->markbits()->IsClean()); | 266 VerifyMarkbitsAreClean(heap_->new_space()); |
| 240 } | 267 } |
| 241 #endif | 268 #endif |
| 242 | 269 |
| 243 | 270 |
| 244 bool IncrementalMarking::WorthActivating() { | 271 bool IncrementalMarking::WorthActivating() { |
| 245 #ifndef DEBUG | 272 #ifndef DEBUG |
| 246 static const intptr_t kActivationThreshold = 8 * MB; | 273 static const intptr_t kActivationThreshold = 8 * MB; |
| 247 #else | 274 #else |
| 248 // TODO(gc) consider setting this to some low level so that some | 275 // TODO(gc) consider setting this to some low level so that some |
| 249 // debug tests run with incremental marking and some without. | 276 // debug tests run with incremental marking and some without. |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 | 368 |
| 342 // Ready to start incremental marking. | 369 // Ready to start incremental marking. |
| 343 if (FLAG_trace_incremental_marking) { | 370 if (FLAG_trace_incremental_marking) { |
| 344 PrintF("[IncrementalMarking] Running\n"); | 371 PrintF("[IncrementalMarking] Running\n"); |
| 345 } | 372 } |
| 346 } | 373 } |
| 347 | 374 |
| 348 | 375 |
| 349 void IncrementalMarking::PrepareForScavenge() { | 376 void IncrementalMarking::PrepareForScavenge() { |
| 350 if (!IsMarking()) return; | 377 if (!IsMarking()) return; |
| 351 heap_->new_space()->InactivePage()->markbits()->Clear(); | 378 NewSpacePageIterator it(heap_->new_space()->FromSpaceLow(), |
| 379 heap_->new_space()->FromSpaceHigh()); |
| 380 while (it.has_next()) { |
| 381 it.next()->markbits()->Clear(); |
| 382 } |
| 352 } | 383 } |
| 353 | 384 |
| 354 | 385 |
| 355 void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { | 386 void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { |
| 356 if (!IsMarking()) return; | 387 if (!IsMarking()) return; |
| 357 | 388 |
| 358 intptr_t current = marking_deque_.bottom(); | 389 intptr_t current = marking_deque_.bottom(); |
| 359 intptr_t mask = marking_deque_.mask(); | 390 intptr_t mask = marking_deque_.mask(); |
| 360 intptr_t limit = marking_deque_.top(); | 391 intptr_t limit = marking_deque_.top(); |
| 361 HeapObject** array = marking_deque_.array(); | 392 HeapObject** array = marking_deque_.array(); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 void IncrementalMarking::Abort() { | 454 void IncrementalMarking::Abort() { |
| 424 if (IsStopped()) return; | 455 if (IsStopped()) return; |
| 425 if (FLAG_trace_incremental_marking) { | 456 if (FLAG_trace_incremental_marking) { |
| 426 PrintF("[IncrementalMarking] Aborting.\n"); | 457 PrintF("[IncrementalMarking] Aborting.\n"); |
| 427 } | 458 } |
| 428 heap_->new_space()->LowerInlineAllocationLimit(0); | 459 heap_->new_space()->LowerInlineAllocationLimit(0); |
| 429 IncrementalMarking::set_should_hurry(false); | 460 IncrementalMarking::set_should_hurry(false); |
| 430 ResetStepCounters(); | 461 ResetStepCounters(); |
| 431 if (IsMarking()) { | 462 if (IsMarking()) { |
| 432 PatchIncrementalMarkingRecordWriteStubs(false); | 463 PatchIncrementalMarkingRecordWriteStubs(false); |
| 433 DeactivateWriteBarrier(); | 464 DeactivateIncrementalWriteBarrier(); |
| 434 } | 465 } |
| 435 heap_->isolate()->stack_guard()->Continue(GC_REQUEST); | 466 heap_->isolate()->stack_guard()->Continue(GC_REQUEST); |
| 436 state_ = STOPPED; | 467 state_ = STOPPED; |
| 437 } | 468 } |
| 438 | 469 |
| 439 | 470 |
| 440 void IncrementalMarking::Finalize() { | 471 void IncrementalMarking::Finalize() { |
| 441 Hurry(); | 472 Hurry(); |
| 442 state_ = STOPPED; | 473 state_ = STOPPED; |
| 443 heap_->new_space()->LowerInlineAllocationLimit(0); | 474 heap_->new_space()->LowerInlineAllocationLimit(0); |
| 444 IncrementalMarking::set_should_hurry(false); | 475 IncrementalMarking::set_should_hurry(false); |
| 445 ResetStepCounters(); | 476 ResetStepCounters(); |
| 446 PatchIncrementalMarkingRecordWriteStubs(false); | 477 PatchIncrementalMarkingRecordWriteStubs(false); |
| 447 DeactivateWriteBarrier(); | 478 DeactivateIncrementalWriteBarrier(); |
| 448 ASSERT(marking_deque_.IsEmpty()); | 479 ASSERT(marking_deque_.IsEmpty()); |
| 449 heap_->isolate()->stack_guard()->Continue(GC_REQUEST); | 480 heap_->isolate()->stack_guard()->Continue(GC_REQUEST); |
| 450 } | 481 } |
| 451 | 482 |
| 452 | 483 |
| 453 void IncrementalMarking::MarkingComplete() { | 484 void IncrementalMarking::MarkingComplete() { |
| 454 state_ = COMPLETE; | 485 state_ = COMPLETE; |
| 455 // We will set the stack guard to request a GC now. This will mean the rest | 486 // We will set the stack guard to request a GC now. This will mean the rest |
| 456 // of the GC gets performed as soon as possible (we can't do a GC here in a | 487 // of the GC gets performed as soon as possible (we can't do a GC here in a |
| 457 // record-write context). If a few things get allocated between now and then | 488 // record-write context). If a few things get allocated between now and then |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 } | 558 } |
| 528 | 559 |
| 529 if (FLAG_trace_incremental_marking || FLAG_trace_gc) { | 560 if (FLAG_trace_incremental_marking || FLAG_trace_gc) { |
| 530 double end = OS::TimeCurrentMillis(); | 561 double end = OS::TimeCurrentMillis(); |
| 531 steps_took_ += (end - start); | 562 steps_took_ += (end - start); |
| 532 } | 563 } |
| 533 } | 564 } |
| 534 | 565 |
| 535 | 566 |
| 536 } } // namespace v8::internal | 567 } } // namespace v8::internal |
| OLD | NEW |