| 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 | 108 |
| 109 | 109 |
| 110 class IncrementalMarkingMarkingVisitor : public ObjectVisitor { | 110 class IncrementalMarkingMarkingVisitor : public ObjectVisitor { |
| 111 public: | 111 public: |
| 112 IncrementalMarkingMarkingVisitor(Heap* heap, | 112 IncrementalMarkingMarkingVisitor(Heap* heap, |
| 113 IncrementalMarking* incremental_marking) | 113 IncrementalMarking* incremental_marking) |
| 114 : heap_(heap), | 114 : heap_(heap), |
| 115 incremental_marking_(incremental_marking) { | 115 incremental_marking_(incremental_marking) { |
| 116 } | 116 } |
| 117 | 117 |
| 118 void VisitEmbeddedPointer(Code* host, Object** p) { |
| 119 Object* obj = *p; |
| 120 if (obj->NonFailureIsHeapObject()) { |
| 121 heap_->mark_compact_collector()->RecordSlot( |
| 122 reinterpret_cast<Object**>(host), |
| 123 p, |
| 124 obj); |
| 125 MarkObject(obj); |
| 126 } |
| 127 } |
| 128 |
| 118 void VisitCodeTarget(RelocInfo* rinfo) { | 129 void VisitCodeTarget(RelocInfo* rinfo) { |
| 119 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 130 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
| 120 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 131 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
| 121 heap_->mark_compact_collector()->RecordRelocSlot(rinfo, Code::cast(target)); | 132 heap_->mark_compact_collector()->RecordRelocSlot(rinfo, Code::cast(target)); |
| 122 MarkObject(target); | 133 MarkObject(target); |
| 123 } | 134 } |
| 124 | 135 |
| 125 void VisitDebugTarget(RelocInfo* rinfo) { | 136 void VisitDebugTarget(RelocInfo* rinfo) { |
| 126 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && | 137 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && |
| 127 rinfo->IsPatchedReturnSequence()) || | 138 rinfo->IsPatchedReturnSequence()) || |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 } | 222 } |
| 212 } | 223 } |
| 213 } | 224 } |
| 214 | 225 |
| 215 Heap* heap_; | 226 Heap* heap_; |
| 216 IncrementalMarking* incremental_marking_; | 227 IncrementalMarking* incremental_marking_; |
| 217 }; | 228 }; |
| 218 | 229 |
| 219 | 230 |
| 220 void IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk, | 231 void IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk, |
| 221 bool is_marking) { | 232 bool is_marking, |
| 233 bool is_compacting) { |
| 222 if (is_marking) { | 234 if (is_marking) { |
| 223 chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); | 235 chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); |
| 224 chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); | 236 chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); |
| 237 |
| 238 // It's difficult to filter out slots recorded for large objects. |
| 239 if (chunk->owner()->identity() == LO_SPACE && |
| 240 chunk->size() > static_cast<size_t>(Page::kPageSize) && |
| 241 is_compacting) { |
| 242 chunk->SetFlag(MemoryChunk::RESCAN_ON_EVACUATION); |
| 243 } |
| 225 } else if (chunk->owner()->identity() == CELL_SPACE || | 244 } else if (chunk->owner()->identity() == CELL_SPACE || |
| 226 chunk->scan_on_scavenge()) { | 245 chunk->scan_on_scavenge()) { |
| 227 chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); | 246 chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); |
| 228 chunk->ClearFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); | 247 chunk->ClearFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); |
| 229 } else { | 248 } else { |
| 230 chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); | 249 chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); |
| 231 chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); | 250 chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); |
| 232 } | 251 } |
| 233 } | 252 } |
| 234 | 253 |
| 235 | 254 |
| 236 void IncrementalMarking::SetNewSpacePageFlags(NewSpacePage* chunk, | 255 void IncrementalMarking::SetNewSpacePageFlags(NewSpacePage* chunk, |
| 237 bool is_marking) { | 256 bool is_marking) { |
| 238 chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); | 257 chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); |
| 239 if (is_marking) { | 258 if (is_marking) { |
| 240 chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); | 259 chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); |
| 241 } else { | 260 } else { |
| 242 chunk->ClearFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); | 261 chunk->ClearFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); |
| 243 } | 262 } |
| 244 chunk->SetFlag(MemoryChunk::SCAN_ON_SCAVENGE); | 263 chunk->SetFlag(MemoryChunk::SCAN_ON_SCAVENGE); |
| 245 } | 264 } |
| 246 | 265 |
| 247 | 266 |
| 248 void IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace( | 267 void IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace( |
| 249 PagedSpace* space) { | 268 PagedSpace* space) { |
| 250 PageIterator it(space); | 269 PageIterator it(space); |
| 251 while (it.has_next()) { | 270 while (it.has_next()) { |
| 252 Page* p = it.next(); | 271 Page* p = it.next(); |
| 253 SetOldSpacePageFlags(p, false); | 272 SetOldSpacePageFlags(p, false, false); |
| 254 } | 273 } |
| 255 } | 274 } |
| 256 | 275 |
| 257 | 276 |
| 258 void IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace( | 277 void IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace( |
| 259 NewSpace* space) { | 278 NewSpace* space) { |
| 260 NewSpacePageIterator it(space); | 279 NewSpacePageIterator it(space); |
| 261 while (it.has_next()) { | 280 while (it.has_next()) { |
| 262 NewSpacePage* p = it.next(); | 281 NewSpacePage* p = it.next(); |
| 263 SetNewSpacePageFlags(p, false); | 282 SetNewSpacePageFlags(p, false); |
| 264 } | 283 } |
| 265 } | 284 } |
| 266 | 285 |
| 267 | 286 |
| 268 void IncrementalMarking::DeactivateIncrementalWriteBarrier() { | 287 void IncrementalMarking::DeactivateIncrementalWriteBarrier() { |
| 269 DeactivateIncrementalWriteBarrierForSpace(heap_->old_pointer_space()); | 288 DeactivateIncrementalWriteBarrierForSpace(heap_->old_pointer_space()); |
| 270 DeactivateIncrementalWriteBarrierForSpace(heap_->old_data_space()); | 289 DeactivateIncrementalWriteBarrierForSpace(heap_->old_data_space()); |
| 271 DeactivateIncrementalWriteBarrierForSpace(heap_->cell_space()); | 290 DeactivateIncrementalWriteBarrierForSpace(heap_->cell_space()); |
| 272 DeactivateIncrementalWriteBarrierForSpace(heap_->map_space()); | 291 DeactivateIncrementalWriteBarrierForSpace(heap_->map_space()); |
| 273 DeactivateIncrementalWriteBarrierForSpace(heap_->code_space()); | 292 DeactivateIncrementalWriteBarrierForSpace(heap_->code_space()); |
| 274 DeactivateIncrementalWriteBarrierForSpace(heap_->new_space()); | 293 DeactivateIncrementalWriteBarrierForSpace(heap_->new_space()); |
| 275 | 294 |
| 276 LargePage* lop = heap_->lo_space()->first_page(); | 295 LargePage* lop = heap_->lo_space()->first_page(); |
| 277 while (lop->is_valid()) { | 296 while (lop->is_valid()) { |
| 278 SetOldSpacePageFlags(lop, false); | 297 SetOldSpacePageFlags(lop, false, false); |
| 279 lop = lop->next_page(); | 298 lop = lop->next_page(); |
| 280 } | 299 } |
| 281 } | 300 } |
| 282 | 301 |
| 283 | 302 |
| 284 void IncrementalMarking::ActivateIncrementalWriteBarrier(PagedSpace* space) { | 303 void IncrementalMarking::ActivateIncrementalWriteBarrier(PagedSpace* space) { |
| 285 PageIterator it(space); | 304 PageIterator it(space); |
| 286 while (it.has_next()) { | 305 while (it.has_next()) { |
| 287 Page* p = it.next(); | 306 Page* p = it.next(); |
| 288 SetOldSpacePageFlags(p, true); | 307 SetOldSpacePageFlags(p, true, is_compacting_); |
| 289 } | 308 } |
| 290 } | 309 } |
| 291 | 310 |
| 292 | 311 |
| 293 void IncrementalMarking::ActivateIncrementalWriteBarrier(NewSpace* space) { | 312 void IncrementalMarking::ActivateIncrementalWriteBarrier(NewSpace* space) { |
| 294 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); | 313 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); |
| 295 while (it.has_next()) { | 314 while (it.has_next()) { |
| 296 NewSpacePage* p = it.next(); | 315 NewSpacePage* p = it.next(); |
| 297 SetNewSpacePageFlags(p, true); | 316 SetNewSpacePageFlags(p, true); |
| 298 } | 317 } |
| 299 } | 318 } |
| 300 | 319 |
| 301 | 320 |
| 302 void IncrementalMarking::ActivateIncrementalWriteBarrier() { | 321 void IncrementalMarking::ActivateIncrementalWriteBarrier() { |
| 303 ActivateIncrementalWriteBarrier(heap_->old_pointer_space()); | 322 ActivateIncrementalWriteBarrier(heap_->old_pointer_space()); |
| 304 ActivateIncrementalWriteBarrier(heap_->old_data_space()); | 323 ActivateIncrementalWriteBarrier(heap_->old_data_space()); |
| 305 ActivateIncrementalWriteBarrier(heap_->cell_space()); | 324 ActivateIncrementalWriteBarrier(heap_->cell_space()); |
| 306 ActivateIncrementalWriteBarrier(heap_->map_space()); | 325 ActivateIncrementalWriteBarrier(heap_->map_space()); |
| 307 ActivateIncrementalWriteBarrier(heap_->code_space()); | 326 ActivateIncrementalWriteBarrier(heap_->code_space()); |
| 308 ActivateIncrementalWriteBarrier(heap_->new_space()); | 327 ActivateIncrementalWriteBarrier(heap_->new_space()); |
| 309 | 328 |
| 310 LargePage* lop = heap_->lo_space()->first_page(); | 329 LargePage* lop = heap_->lo_space()->first_page(); |
| 311 while (lop->is_valid()) { | 330 while (lop->is_valid()) { |
| 312 SetOldSpacePageFlags(lop, true); | 331 SetOldSpacePageFlags(lop, true, is_compacting_); |
| 313 lop = lop->next_page(); | 332 lop = lop->next_page(); |
| 314 } | 333 } |
| 315 } | 334 } |
| 316 | 335 |
| 317 | 336 |
| 318 bool IncrementalMarking::WorthActivating() { | 337 bool IncrementalMarking::WorthActivating() { |
| 319 #ifndef DEBUG | 338 #ifndef DEBUG |
| 320 static const intptr_t kActivationThreshold = 8 * MB; | 339 static const intptr_t kActivationThreshold = 8 * MB; |
| 321 #else | 340 #else |
| 322 // TODO(gc) consider setting this to some low level so that some | 341 // TODO(gc) consider setting this to some low level so that some |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 | 465 |
| 447 heap_->CompletelyClearInstanceofCache(); | 466 heap_->CompletelyClearInstanceofCache(); |
| 448 heap_->isolate()->compilation_cache()->MarkCompactPrologue(); | 467 heap_->isolate()->compilation_cache()->MarkCompactPrologue(); |
| 449 | 468 |
| 450 if (FLAG_cleanup_code_caches_at_gc) { | 469 if (FLAG_cleanup_code_caches_at_gc) { |
| 451 // We will mark cache black with a separate pass | 470 // We will mark cache black with a separate pass |
| 452 // when we finish marking. | 471 // when we finish marking. |
| 453 MarkObjectGreyDoNotEnqueue(heap_->polymorphic_code_cache()); | 472 MarkObjectGreyDoNotEnqueue(heap_->polymorphic_code_cache()); |
| 454 } | 473 } |
| 455 | 474 |
| 456 if (is_compacting_) { | |
| 457 // It's difficult to filter out slots recorded for large objects. | |
| 458 LargeObjectIterator it(heap_->lo_space()); | |
| 459 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | |
| 460 if (obj->IsFixedArray() || obj->IsCode()) { | |
| 461 Page* p = Page::FromAddress(obj->address()); | |
| 462 if (p->size() > static_cast<size_t>(Page::kPageSize)) { | |
| 463 p->SetFlag(Page::RESCAN_ON_EVACUATION); | |
| 464 } | |
| 465 } | |
| 466 } | |
| 467 } | |
| 468 | |
| 469 // Mark strong roots grey. | 475 // Mark strong roots grey. |
| 470 IncrementalMarkingRootMarkingVisitor visitor(heap_, this); | 476 IncrementalMarkingRootMarkingVisitor visitor(heap_, this); |
| 471 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); | 477 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); |
| 472 | 478 |
| 473 // Ready to start incremental marking. | 479 // Ready to start incremental marking. |
| 474 if (FLAG_trace_incremental_marking) { | 480 if (FLAG_trace_incremental_marking) { |
| 475 PrintF("[IncrementalMarking] Running\n"); | 481 PrintF("[IncrementalMarking] Running\n"); |
| 476 } | 482 } |
| 477 } | 483 } |
| 478 | 484 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 bytes_rescanned_ = 0; | 800 bytes_rescanned_ = 0; |
| 795 allocation_marking_factor_ = kInitialAllocationMarkingFactor; | 801 allocation_marking_factor_ = kInitialAllocationMarkingFactor; |
| 796 } | 802 } |
| 797 | 803 |
| 798 | 804 |
| 799 int64_t IncrementalMarking::SpaceLeftInOldSpace() { | 805 int64_t IncrementalMarking::SpaceLeftInOldSpace() { |
| 800 return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSize(); | 806 return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSize(); |
| 801 } | 807 } |
| 802 | 808 |
| 803 } } // namespace v8::internal | 809 } } // namespace v8::internal |
| OLD | NEW |