| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 // Mark object pointed to by p. | 79 // Mark object pointed to by p. |
| 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 if (incremental_marking_->MarkBlackOrKeepGrey(mark_bit)) { |
| 90 MemoryChunk::IncrementLiveBytes(heap_object->address(), |
| 91 heap_object->Size()); |
| 92 } |
| 90 } else if (Marking::IsWhite(mark_bit)) { | 93 } else if (Marking::IsWhite(mark_bit)) { |
| 91 incremental_marking_->WhiteToGreyAndPush(heap_object, mark_bit); | 94 incremental_marking_->WhiteToGreyAndPush(heap_object, mark_bit); |
| 92 } | 95 } |
| 93 } | 96 } |
| 94 } | 97 } |
| 95 | 98 |
| 96 Heap* heap_; | 99 Heap* heap_; |
| 97 IncrementalMarking* incremental_marking_; | 100 IncrementalMarking* incremental_marking_; |
| 98 }; | 101 }; |
| 99 | 102 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 115 } | 118 } |
| 116 | 119 |
| 117 private: | 120 private: |
| 118 void MarkObjectByPointer(Object** p) { | 121 void MarkObjectByPointer(Object** p) { |
| 119 Object* obj = *p; | 122 Object* obj = *p; |
| 120 if (!obj->IsHeapObject()) return; | 123 if (!obj->IsHeapObject()) return; |
| 121 | 124 |
| 122 HeapObject* heap_object = HeapObject::cast(obj); | 125 HeapObject* heap_object = HeapObject::cast(obj); |
| 123 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); | 126 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); |
| 124 if (mark_bit.data_only()) { | 127 if (mark_bit.data_only()) { |
| 125 incremental_marking_->MarkBlackOrKeepGrey(mark_bit); | 128 if (incremental_marking_->MarkBlackOrKeepGrey(mark_bit)) { |
| 129 MemoryChunk::IncrementLiveBytes(heap_object->address(), |
| 130 heap_object->Size()); |
| 131 } |
| 126 } else { | 132 } else { |
| 127 if (Marking::IsWhite(mark_bit)) { | 133 if (Marking::IsWhite(mark_bit)) { |
| 128 incremental_marking_->WhiteToGreyAndPush(heap_object, mark_bit); | 134 incremental_marking_->WhiteToGreyAndPush(heap_object, mark_bit); |
| 129 } | 135 } |
| 130 } | 136 } |
| 131 } | 137 } |
| 132 | 138 |
| 133 Heap* heap_; | 139 Heap* heap_; |
| 134 IncrementalMarking* incremental_marking_; | 140 IncrementalMarking* incremental_marking_; |
| 135 }; | 141 }; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 SetOldSpacePageFlags(lop, false); | 202 SetOldSpacePageFlags(lop, false); |
| 197 lop = lop->next_page(); | 203 lop = lop->next_page(); |
| 198 } | 204 } |
| 199 } | 205 } |
| 200 | 206 |
| 201 | 207 |
| 202 void IncrementalMarking::ClearMarkbits(PagedSpace* space) { | 208 void IncrementalMarking::ClearMarkbits(PagedSpace* space) { |
| 203 PageIterator it(space); | 209 PageIterator it(space); |
| 204 while (it.has_next()) { | 210 while (it.has_next()) { |
| 205 Page* p = it.next(); | 211 Page* p = it.next(); |
| 206 p->markbits()->Clear(); | 212 Bitmap::Clear(p); |
| 207 SetOldSpacePageFlags(p, true); | 213 SetOldSpacePageFlags(p, true); |
| 208 } | 214 } |
| 209 } | 215 } |
| 210 | 216 |
| 211 | 217 |
| 212 void IncrementalMarking::ClearMarkbits(NewSpace* space) { | 218 void IncrementalMarking::ClearMarkbits(NewSpace* space) { |
| 213 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); | 219 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); |
| 214 while (it.has_next()) { | 220 while (it.has_next()) { |
| 215 NewSpacePage* p = it.next(); | 221 NewSpacePage* p = it.next(); |
| 216 p->markbits()->Clear(); | 222 Bitmap::Clear(p); |
| 217 SetNewSpacePageFlags(p, true); | 223 SetNewSpacePageFlags(p, true); |
| 218 } | 224 } |
| 219 } | 225 } |
| 220 | 226 |
| 221 | 227 |
| 222 void IncrementalMarking::ClearMarkbits() { | 228 void IncrementalMarking::ClearMarkbits() { |
| 223 // TODO(gc): Clear the mark bits in the sweeper. | 229 // TODO(gc): Clear the mark bits in the sweeper. |
| 224 ClearMarkbits(heap_->old_pointer_space()); | 230 ClearMarkbits(heap_->old_pointer_space()); |
| 225 ClearMarkbits(heap_->old_data_space()); | 231 ClearMarkbits(heap_->old_data_space()); |
| 226 ClearMarkbits(heap_->cell_space()); | 232 ClearMarkbits(heap_->cell_space()); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 PrintF("[IncrementalMarking] Running\n"); | 377 PrintF("[IncrementalMarking] Running\n"); |
| 372 } | 378 } |
| 373 } | 379 } |
| 374 | 380 |
| 375 | 381 |
| 376 void IncrementalMarking::PrepareForScavenge() { | 382 void IncrementalMarking::PrepareForScavenge() { |
| 377 if (!IsMarking()) return; | 383 if (!IsMarking()) return; |
| 378 NewSpacePageIterator it(heap_->new_space()->FromSpaceStart(), | 384 NewSpacePageIterator it(heap_->new_space()->FromSpaceStart(), |
| 379 heap_->new_space()->FromSpaceEnd()); | 385 heap_->new_space()->FromSpaceEnd()); |
| 380 while (it.has_next()) { | 386 while (it.has_next()) { |
| 381 it.next()->markbits()->Clear(); | 387 Bitmap::Clear(it.next()); |
| 382 } | 388 } |
| 383 } | 389 } |
| 384 | 390 |
| 385 | 391 |
| 386 void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { | 392 void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { |
| 387 if (!IsMarking()) return; | 393 if (!IsMarking()) return; |
| 388 | 394 |
| 389 intptr_t current = marking_deque_.bottom(); | 395 intptr_t current = marking_deque_.bottom(); |
| 390 intptr_t mask = marking_deque_.mask(); | 396 intptr_t mask = marking_deque_.mask(); |
| 391 intptr_t limit = marking_deque_.top(); | 397 intptr_t limit = marking_deque_.top(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 Map* filler_map = heap_->one_pointer_filler_map(); | 437 Map* filler_map = heap_->one_pointer_filler_map(); |
| 432 IncrementalMarkingMarkingVisitor marking_visitor(heap_, this); | 438 IncrementalMarkingMarkingVisitor marking_visitor(heap_, this); |
| 433 while (!marking_deque_.IsEmpty()) { | 439 while (!marking_deque_.IsEmpty()) { |
| 434 HeapObject* obj = marking_deque_.Pop(); | 440 HeapObject* obj = marking_deque_.Pop(); |
| 435 | 441 |
| 436 // Explicitly skip one word fillers. Incremental markbit patterns are | 442 // Explicitly skip one word fillers. Incremental markbit patterns are |
| 437 // correct only for objects that occupy at least two words. | 443 // correct only for objects that occupy at least two words. |
| 438 if (obj->map() != filler_map) { | 444 if (obj->map() != filler_map) { |
| 439 obj->Iterate(&marking_visitor); | 445 obj->Iterate(&marking_visitor); |
| 440 MarkBit mark_bit = Marking::MarkBitFrom(obj); | 446 MarkBit mark_bit = Marking::MarkBitFrom(obj); |
| 447 ASSERT(!Marking::IsBlack(mark_bit)); |
| 441 Marking::MarkBlack(mark_bit); | 448 Marking::MarkBlack(mark_bit); |
| 449 MemoryChunk::IncrementLiveBytes(obj->address(), obj->Size()); |
| 442 } | 450 } |
| 443 } | 451 } |
| 444 state_ = COMPLETE; | 452 state_ = COMPLETE; |
| 445 if (FLAG_trace_incremental_marking) { | 453 if (FLAG_trace_incremental_marking) { |
| 446 double end = OS::TimeCurrentMillis(); | 454 double end = OS::TimeCurrentMillis(); |
| 447 PrintF("[IncrementalMarking] Complete (hurry), spent %d ms.\n", | 455 PrintF("[IncrementalMarking] Complete (hurry), spent %d ms.\n", |
| 448 static_cast<int>(end - start)); | 456 static_cast<int>(end - start)); |
| 449 } | 457 } |
| 450 } | 458 } |
| 451 } | 459 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 ASSERT(Marking::IsGrey(Marking::MarkBitFrom(obj))); | 540 ASSERT(Marking::IsGrey(Marking::MarkBitFrom(obj))); |
| 533 int size = obj->SizeFromMap(map); | 541 int size = obj->SizeFromMap(map); |
| 534 bytes_to_process -= size; | 542 bytes_to_process -= size; |
| 535 MarkBit map_mark_bit = Marking::MarkBitFrom(map); | 543 MarkBit map_mark_bit = Marking::MarkBitFrom(map); |
| 536 if (Marking::IsWhite(map_mark_bit)) { | 544 if (Marking::IsWhite(map_mark_bit)) { |
| 537 WhiteToGreyAndPush(map, map_mark_bit); | 545 WhiteToGreyAndPush(map, map_mark_bit); |
| 538 } | 546 } |
| 539 // TODO(gc) switch to static visitor instead of normal visitor. | 547 // TODO(gc) switch to static visitor instead of normal visitor. |
| 540 obj->IterateBody(map->instance_type(), size, &marking_visitor); | 548 obj->IterateBody(map->instance_type(), size, &marking_visitor); |
| 541 MarkBit obj_mark_bit = Marking::MarkBitFrom(obj); | 549 MarkBit obj_mark_bit = Marking::MarkBitFrom(obj); |
| 550 ASSERT(!Marking::IsBlack(obj_mark_bit)); |
| 542 Marking::MarkBlack(obj_mark_bit); | 551 Marking::MarkBlack(obj_mark_bit); |
| 552 MemoryChunk::IncrementLiveBytes(obj->address(), size); |
| 543 } | 553 } |
| 544 } | 554 } |
| 545 if (marking_deque_.IsEmpty()) MarkingComplete(); | 555 if (marking_deque_.IsEmpty()) MarkingComplete(); |
| 546 } | 556 } |
| 547 | 557 |
| 548 allocated_ = 0; | 558 allocated_ = 0; |
| 549 | 559 |
| 550 steps_count_++; | 560 steps_count_++; |
| 551 | 561 |
| 552 if ((steps_count_ % kAllocationMarkingFactorSpeedupInterval) == 0) { | 562 if ((steps_count_ % kAllocationMarkingFactorSpeedupInterval) == 0) { |
| 553 allocation_marking_factor_ += kAllocationMarkingFactorSpeedup; | 563 allocation_marking_factor_ += kAllocationMarkingFactorSpeedup; |
| 554 allocation_marking_factor_ *= 1.3; | 564 allocation_marking_factor_ *= 1.3; |
| 555 if (FLAG_trace_gc) { | 565 if (FLAG_trace_gc) { |
| 556 PrintF("Marking speed increased to %d\n", allocation_marking_factor_); | 566 PrintF("Marking speed increased to %d\n", allocation_marking_factor_); |
| 557 } | 567 } |
| 558 } | 568 } |
| 559 | 569 |
| 560 if (FLAG_trace_incremental_marking || FLAG_trace_gc) { | 570 if (FLAG_trace_incremental_marking || FLAG_trace_gc) { |
| 561 double end = OS::TimeCurrentMillis(); | 571 double end = OS::TimeCurrentMillis(); |
| 562 steps_took_ += (end - start); | 572 steps_took_ += (end - start); |
| 563 } | 573 } |
| 564 } | 574 } |
| 565 | 575 |
| 566 | 576 |
| 567 } } // namespace v8::internal | 577 } } // namespace v8::internal |
| OLD | NEW |