Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 } | 363 } |
| 364 | 364 |
| 365 | 365 |
| 366 // Visit an unmarked object. | 366 // Visit an unmarked object. |
| 367 static inline void VisitUnmarkedObject(HeapObject* obj) { | 367 static inline void VisitUnmarkedObject(HeapObject* obj) { |
| 368 #ifdef DEBUG | 368 #ifdef DEBUG |
| 369 ASSERT(HEAP->Contains(obj)); | 369 ASSERT(HEAP->Contains(obj)); |
| 370 ASSERT(!obj->IsMarked()); | 370 ASSERT(!obj->IsMarked()); |
| 371 #endif | 371 #endif |
| 372 Map* map = obj->map(); | 372 Map* map = obj->map(); |
| 373 HEAP->mark_compact_collector()->SetMark(obj); | 373 map->heap()->mark_compact_collector()->SetMark(obj); |
| 374 // Mark the map pointer and the body. | 374 // Mark the map pointer and the body. |
| 375 HEAP->mark_compact_collector()->MarkObject(map); | 375 map->heap()->mark_compact_collector()->MarkObject(map); |
| 376 IterateBody(map, obj); | 376 IterateBody(map, obj); |
| 377 } | 377 } |
| 378 | 378 |
| 379 // Visit all unmarked objects pointed to by [start, end). | 379 // Visit all unmarked objects pointed to by [start, end). |
| 380 // Returns false if the operation fails (lack of stack space). | 380 // Returns false if the operation fails (lack of stack space). |
| 381 static inline bool VisitUnmarkedObjects(Object** start, Object** end) { | 381 static inline bool VisitUnmarkedObjects(Object** start, Object** end) { |
| 382 // Return false is we are close to the stack limit. | 382 // Return false is we are close to the stack limit. |
| 383 StackLimitCheck check; | 383 StackLimitCheck check; |
| 384 if (check.HasOverflowed()) return false; | 384 if (check.HasOverflowed()) return false; |
| 385 | 385 |
| (...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1606 current += | 1606 current += |
| 1607 StaticPointersToNewGenUpdatingVisitor::IterateBody(object->map(), | 1607 StaticPointersToNewGenUpdatingVisitor::IterateBody(object->map(), |
| 1608 object); | 1608 object); |
| 1609 } | 1609 } |
| 1610 | 1610 |
| 1611 // Update roots. | 1611 // Update roots. |
| 1612 heap->IterateRoots(&updating_visitor, VISIT_ALL_IN_SCAVENGE); | 1612 heap->IterateRoots(&updating_visitor, VISIT_ALL_IN_SCAVENGE); |
| 1613 | 1613 |
| 1614 // Update pointers in old spaces. | 1614 // Update pointers in old spaces. |
| 1615 heap->IterateDirtyRegions(heap->old_pointer_space(), | 1615 heap->IterateDirtyRegions(heap->old_pointer_space(), |
| 1616 &heap->IteratePointersInDirtyRegion, | 1616 &Heap::IteratePointersInDirtyRegion, |
| 1617 &UpdatePointerToNewGen, | 1617 &UpdatePointerToNewGen, |
| 1618 heap->WATERMARK_SHOULD_BE_VALID); | 1618 heap->WATERMARK_SHOULD_BE_VALID); |
| 1619 | 1619 |
| 1620 heap->lo_space()->IterateDirtyRegions(&UpdatePointerToNewGen); | 1620 heap->lo_space()->IterateDirtyRegions(&UpdatePointerToNewGen); |
| 1621 | 1621 |
| 1622 // Update pointers from cells. | 1622 // Update pointers from cells. |
| 1623 HeapObjectIterator cell_iterator(heap->cell_space()); | 1623 HeapObjectIterator cell_iterator(heap->cell_space()); |
| 1624 for (HeapObject* cell = cell_iterator.next(); | 1624 for (HeapObject* cell = cell_iterator.next(); |
| 1625 cell != NULL; | 1625 cell != NULL; |
| 1626 cell = cell_iterator.next()) { | 1626 cell = cell_iterator.next()) { |
| (...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2403 USE(live_cells_size); | 2403 USE(live_cells_size); |
| 2404 USE(live_news_size); | 2404 USE(live_news_size); |
| 2405 ASSERT(live_maps_size == live_map_objects_size_); | 2405 ASSERT(live_maps_size == live_map_objects_size_); |
| 2406 ASSERT(live_data_olds_size == live_old_data_objects_size_); | 2406 ASSERT(live_data_olds_size == live_old_data_objects_size_); |
| 2407 ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_); | 2407 ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_); |
| 2408 ASSERT(live_codes_size == live_code_objects_size_); | 2408 ASSERT(live_codes_size == live_code_objects_size_); |
| 2409 ASSERT(live_cells_size == live_cell_objects_size_); | 2409 ASSERT(live_cells_size == live_cell_objects_size_); |
| 2410 ASSERT(live_news_size == live_young_objects_size_); | 2410 ASSERT(live_news_size == live_young_objects_size_); |
| 2411 | 2411 |
| 2412 // Flip from and to spaces | 2412 // Flip from and to spaces |
| 2413 HEAP->new_space()->Flip(); | 2413 heap_->new_space()->Flip(); |
| 2414 | 2414 |
| 2415 HEAP->new_space()->MCCommitRelocationInfo(); | 2415 heap_->new_space()->MCCommitRelocationInfo(); |
| 2416 | 2416 |
| 2417 // Set age_mark to bottom in to space | 2417 // Set age_mark to bottom in to space |
| 2418 Address mark = HEAP->new_space()->bottom(); | 2418 Address mark = heap_->new_space()->bottom(); |
| 2419 HEAP->new_space()->set_age_mark(mark); | 2419 heap_->new_space()->set_age_mark(mark); |
| 2420 | 2420 |
| 2421 PagedSpaces spaces; | 2421 PagedSpaces spaces; |
| 2422 for (PagedSpace* space = spaces.next(); space != NULL; space = spaces.next()) | 2422 for (PagedSpace* space = spaces.next(); space != NULL; space = spaces.next()) |
| 2423 space->MCCommitRelocationInfo(); | 2423 space->MCCommitRelocationInfo(); |
| 2424 | 2424 |
| 2425 HEAP->CheckNewSpaceExpansionCriteria(); | 2425 heap_->CheckNewSpaceExpansionCriteria(); |
| 2426 HEAP->IncrementYoungSurvivorsCounter(live_news_size); | 2426 heap_->IncrementYoungSurvivorsCounter(live_news_size); |
| 2427 } | 2427 } |
| 2428 | 2428 |
| 2429 | 2429 |
| 2430 int MarkCompactCollector::RelocateMapObject(HeapObject* obj) { | 2430 int MarkCompactCollector::RelocateMapObject(HeapObject* obj) { |
| 2431 // Recover map pointer. | 2431 // Recover map pointer. |
| 2432 MapWord encoding = obj->map_word(); | 2432 MapWord encoding = obj->map_word(); |
| 2433 Address map_addr = encoding.DecodeMapAddress(HEAP->map_space()); | 2433 Address map_addr = encoding.DecodeMapAddress(HEAP->map_space()); |
| 2434 ASSERT(HEAP->map_space()->Contains(HeapObject::FromAddress(map_addr))); | 2434 ASSERT(HEAP->map_space()->Contains(HeapObject::FromAddress(map_addr))); |
| 2435 | 2435 |
| 2436 // Get forwarding address before resetting map pointer | 2436 // Get forwarding address before resetting map pointer |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2479 #ifdef DEBUG | 2479 #ifdef DEBUG |
| 2480 if (FLAG_gc_verbose) { | 2480 if (FLAG_gc_verbose) { |
| 2481 PrintF("relocate %p -> %p\n", obj->address(), new_addr); | 2481 PrintF("relocate %p -> %p\n", obj->address(), new_addr); |
| 2482 } | 2482 } |
| 2483 #endif | 2483 #endif |
| 2484 | 2484 |
| 2485 return obj_size; | 2485 return obj_size; |
| 2486 } | 2486 } |
| 2487 | 2487 |
| 2488 | 2488 |
| 2489 int MarkCompactCollector::RelocateOldNonCodeObject(HeapObject* obj, | 2489 int MarkCompactCollector::RelocateOldNonCodeObject(HeapObject* obj, |
|
Vitaly Repeshko
2010/09/10 12:35:25
It'd be really nice to make MarkCompactCollector::
| |
| 2490 PagedSpace* space) { | 2490 PagedSpace* space) { |
| 2491 // Recover map pointer. | 2491 // Recover map pointer. |
| 2492 MapWord encoding = obj->map_word(); | 2492 MapWord encoding = obj->map_word(); |
| 2493 Address map_addr = encoding.DecodeMapAddress(HEAP->map_space()); | 2493 Address map_addr = encoding.DecodeMapAddress(heap_->map_space()); |
| 2494 ASSERT(HEAP->map_space()->Contains(map_addr)); | 2494 ASSERT(heap_->map_space()->Contains(map_addr)); |
| 2495 | 2495 |
| 2496 // Get forwarding address before resetting map pointer. | 2496 // Get forwarding address before resetting map pointer. |
| 2497 Address new_addr = GetForwardingAddressInOldSpace(obj); | 2497 Address new_addr = GetForwardingAddressInOldSpace(obj); |
| 2498 | 2498 |
| 2499 // Reset the map pointer. | 2499 // Reset the map pointer. |
| 2500 int obj_size = RestoreMap(obj, space, new_addr, map_addr); | 2500 int obj_size = RestoreMap(obj, space, new_addr, map_addr); |
| 2501 | 2501 |
| 2502 Address old_addr = obj->address(); | 2502 Address old_addr = obj->address(); |
| 2503 | 2503 |
| 2504 if (new_addr != old_addr) { | 2504 if (new_addr != old_addr) { |
| 2505 // Move contents. | 2505 // Move contents. |
| 2506 if (space == HEAP->old_data_space()) { | 2506 if (space == heap_->old_data_space()) { |
| 2507 HEAP->MoveBlock(new_addr, old_addr, obj_size); | 2507 heap_->MoveBlock(new_addr, old_addr, obj_size); |
| 2508 } else { | 2508 } else { |
| 2509 HEAP->MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr, | 2509 heap_->MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr, |
| 2510 old_addr, | 2510 old_addr, |
| 2511 obj_size); | 2511 obj_size); |
| 2512 } | 2512 } |
| 2513 } | 2513 } |
| 2514 | 2514 |
| 2515 ASSERT(!HeapObject::FromAddress(new_addr)->IsCode()); | 2515 ASSERT(!HeapObject::FromAddress(new_addr)->IsCode()); |
| 2516 | 2516 |
| 2517 HeapObject* copied_to = HeapObject::FromAddress(new_addr); | 2517 HeapObject* copied_to = HeapObject::FromAddress(new_addr); |
| 2518 if (copied_to->IsJSFunction()) { | 2518 if (copied_to->IsJSFunction()) { |
| 2519 PROFILE(FunctionMoveEvent(old_addr, new_addr)); | 2519 PROFILE(FunctionMoveEvent(old_addr, new_addr)); |
| 2520 } | 2520 } |
| 2521 HEAP_PROFILE(ObjectMoveEvent(old_addr, new_addr)); | 2521 HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr)); |
| 2522 | 2522 |
| 2523 return obj_size; | 2523 return obj_size; |
| 2524 } | 2524 } |
| 2525 | 2525 |
| 2526 | 2526 |
| 2527 int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) { | 2527 int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) { |
| 2528 Heap* heap = HEAP; | 2528 Heap* heap = HEAP; |
| 2529 return heap->mark_compact_collector()->RelocateOldNonCodeObject( | 2529 return heap->mark_compact_collector()->RelocateOldNonCodeObject( |
| 2530 obj, heap->old_pointer_space()); | 2530 obj, heap->old_pointer_space()); |
| 2531 } | 2531 } |
| 2532 | 2532 |
| 2533 | 2533 |
| 2534 int MarkCompactCollector::RelocateOldDataObject(HeapObject* obj) { | 2534 int MarkCompactCollector::RelocateOldDataObject(HeapObject* obj) { |
| 2535 Heap* heap = HEAP; | 2535 Heap* heap = HEAP; |
| 2536 return heap->mark_compact_collector()->RelocateOldNonCodeObject( | 2536 return heap->mark_compact_collector()->RelocateOldNonCodeObject( |
| 2537 obj, heap->old_data_space()); | 2537 obj, heap->old_data_space()); |
| 2538 } | 2538 } |
| 2539 | 2539 |
| 2540 | 2540 |
| 2541 int MarkCompactCollector::RelocateCellObject(HeapObject* obj) { | 2541 int MarkCompactCollector::RelocateCellObject(HeapObject* obj) { |
| 2542 Heap* heap = HEAP; | 2542 Heap* heap = HEAP; |
| 2543 return heap->mark_compact_collector()->RelocateOldNonCodeObject( | 2543 return heap->mark_compact_collector()->RelocateOldNonCodeObject( |
| 2544 obj, heap->cell_space()); | 2544 obj, heap->cell_space()); |
| 2545 } | 2545 } |
| 2546 | 2546 |
| 2547 | 2547 |
| 2548 int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) { | 2548 int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) { |
| 2549 // Recover map pointer. | 2549 // Recover map pointer. |
| 2550 MapWord encoding = obj->map_word(); | 2550 MapWord encoding = obj->map_word(); |
| 2551 Address map_addr = encoding.DecodeMapAddress(HEAP->map_space()); | 2551 Heap* heap = HEAP; |
| 2552 ASSERT(HEAP->map_space()->Contains(HeapObject::FromAddress(map_addr))); | 2552 Address map_addr = encoding.DecodeMapAddress(heap->map_space()); |
| 2553 ASSERT(heap->map_space()->Contains(HeapObject::FromAddress(map_addr))); | |
| 2553 | 2554 |
| 2554 // Get forwarding address before resetting map pointer | 2555 // Get forwarding address before resetting map pointer |
| 2555 Address new_addr = GetForwardingAddressInOldSpace(obj); | 2556 Address new_addr = GetForwardingAddressInOldSpace(obj); |
| 2556 | 2557 |
| 2557 // Reset the map pointer. | 2558 // Reset the map pointer. |
| 2558 int obj_size = RestoreMap(obj, HEAP->code_space(), new_addr, map_addr); | 2559 int obj_size = RestoreMap(obj, heap->code_space(), new_addr, map_addr); |
| 2559 | 2560 |
| 2560 Address old_addr = obj->address(); | 2561 Address old_addr = obj->address(); |
| 2561 | 2562 |
| 2562 if (new_addr != old_addr) { | 2563 if (new_addr != old_addr) { |
| 2563 // Move contents. | 2564 // Move contents. |
| 2564 HEAP->MoveBlock(new_addr, old_addr, obj_size); | 2565 heap->MoveBlock(new_addr, old_addr, obj_size); |
| 2565 } | 2566 } |
| 2566 | 2567 |
| 2567 HeapObject* copied_to = HeapObject::FromAddress(new_addr); | 2568 HeapObject* copied_to = HeapObject::FromAddress(new_addr); |
| 2568 if (copied_to->IsCode()) { | 2569 if (copied_to->IsCode()) { |
| 2569 // May also update inline cache target. | 2570 // May also update inline cache target. |
| 2570 Code::cast(copied_to)->Relocate(new_addr - old_addr); | 2571 Code::cast(copied_to)->Relocate(new_addr - old_addr); |
| 2571 // Notify the logger that compiled code has moved. | 2572 // Notify the logger that compiled code has moved. |
| 2572 PROFILE(CodeMoveEvent(old_addr, new_addr)); | 2573 PROFILE(CodeMoveEvent(old_addr, new_addr)); |
| 2573 } | 2574 } |
| 2574 HEAP_PROFILE(ObjectMoveEvent(old_addr, new_addr)); | 2575 HEAP_PROFILE(heap, ObjectMoveEvent(old_addr, new_addr)); |
| 2575 | 2576 |
| 2576 return obj_size; | 2577 return obj_size; |
| 2577 } | 2578 } |
| 2578 | 2579 |
| 2579 | 2580 |
| 2580 int MarkCompactCollector::RelocateNewObject(HeapObject* obj) { | 2581 int MarkCompactCollector::RelocateNewObject(HeapObject* obj) { |
| 2581 int obj_size = obj->Size(); | 2582 int obj_size = obj->Size(); |
| 2582 | 2583 |
| 2583 // Get forwarding address | 2584 // Get forwarding address |
| 2584 Address old_addr = obj->address(); | 2585 Address old_addr = obj->address(); |
| 2585 int offset = HEAP->new_space()->ToSpaceOffsetForAddress(old_addr); | 2586 Heap* heap = HEAP; |
| 2587 int offset = heap->new_space()->ToSpaceOffsetForAddress(old_addr); | |
| 2586 | 2588 |
| 2587 Address new_addr = | 2589 Address new_addr = |
| 2588 Memory::Address_at(HEAP->new_space()->FromSpaceLow() + offset); | 2590 Memory::Address_at(heap->new_space()->FromSpaceLow() + offset); |
| 2589 | 2591 |
| 2590 #ifdef DEBUG | 2592 #ifdef DEBUG |
| 2591 if (HEAP->new_space()->FromSpaceContains(new_addr)) { | 2593 if (heap->new_space()->FromSpaceContains(new_addr)) { |
| 2592 ASSERT(HEAP->new_space()->FromSpaceOffsetForAddress(new_addr) <= | 2594 ASSERT(heap->new_space()->FromSpaceOffsetForAddress(new_addr) <= |
| 2593 HEAP->new_space()->ToSpaceOffsetForAddress(old_addr)); | 2595 heap->new_space()->ToSpaceOffsetForAddress(old_addr)); |
| 2594 } else { | 2596 } else { |
| 2595 ASSERT(HEAP->TargetSpace(obj) == HEAP->old_pointer_space() || | 2597 ASSERT(heap->TargetSpace(obj) == heap->old_pointer_space() || |
| 2596 HEAP->TargetSpace(obj) == HEAP->old_data_space()); | 2598 heap->TargetSpace(obj) == heap->old_data_space()); |
| 2597 } | 2599 } |
| 2598 #endif | 2600 #endif |
| 2599 | 2601 |
| 2600 // New and old addresses cannot overlap. | 2602 // New and old addresses cannot overlap. |
| 2601 if (HEAP->InNewSpace(HeapObject::FromAddress(new_addr))) { | 2603 if (heap->InNewSpace(HeapObject::FromAddress(new_addr))) { |
| 2602 HEAP->CopyBlock(new_addr, old_addr, obj_size); | 2604 heap->CopyBlock(new_addr, old_addr, obj_size); |
| 2603 } else { | 2605 } else { |
| 2604 HEAP->CopyBlockToOldSpaceAndUpdateRegionMarks(new_addr, | 2606 heap->CopyBlockToOldSpaceAndUpdateRegionMarks(new_addr, |
| 2605 old_addr, | 2607 old_addr, |
| 2606 obj_size); | 2608 obj_size); |
| 2607 } | 2609 } |
| 2608 | 2610 |
| 2609 #ifdef DEBUG | 2611 #ifdef DEBUG |
| 2610 if (FLAG_gc_verbose) { | 2612 if (FLAG_gc_verbose) { |
| 2611 PrintF("relocate %p -> %p\n", old_addr, new_addr); | 2613 PrintF("relocate %p -> %p\n", old_addr, new_addr); |
| 2612 } | 2614 } |
| 2613 #endif | 2615 #endif |
| 2614 | 2616 |
| 2615 HeapObject* copied_to = HeapObject::FromAddress(new_addr); | 2617 HeapObject* copied_to = HeapObject::FromAddress(new_addr); |
| 2616 if (copied_to->IsJSFunction()) { | 2618 if (copied_to->IsJSFunction()) { |
| 2617 PROFILE(FunctionMoveEvent(old_addr, new_addr)); | 2619 PROFILE(FunctionMoveEvent(old_addr, new_addr)); |
| 2618 } | 2620 } |
| 2619 HEAP_PROFILE(ObjectMoveEvent(old_addr, new_addr)); | 2621 HEAP_PROFILE(heap, ObjectMoveEvent(old_addr, new_addr)); |
| 2620 | 2622 |
| 2621 return obj_size; | 2623 return obj_size; |
| 2622 } | 2624 } |
| 2623 | 2625 |
| 2624 | 2626 |
| 2625 void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj) { | 2627 void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj) { |
| 2626 #ifdef ENABLE_LOGGING_AND_PROFILING | 2628 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 2627 if (obj->IsCode()) { | 2629 if (obj->IsCode()) { |
| 2628 PROFILE(CodeDeleteEvent(obj->address())); | 2630 PROFILE(CodeDeleteEvent(obj->address())); |
| 2629 } else if (obj->IsJSFunction()) { | 2631 } else if (obj->IsJSFunction()) { |
| 2630 PROFILE(FunctionDeleteEvent(obj->address())); | 2632 PROFILE(FunctionDeleteEvent(obj->address())); |
| 2631 } | 2633 } |
| 2632 #endif | 2634 #endif |
| 2633 } | 2635 } |
| 2634 | 2636 |
| 2635 | 2637 |
| 2636 void MarkCompactCollector::Initialize() { | 2638 void MarkCompactCollector::Initialize() { |
| 2637 StaticPointersToNewGenUpdatingVisitor::Initialize(); | 2639 StaticPointersToNewGenUpdatingVisitor::Initialize(); |
| 2638 StaticMarkingVisitor::Initialize(); | 2640 StaticMarkingVisitor::Initialize(); |
| 2639 } | 2641 } |
| 2640 | 2642 |
| 2641 | 2643 |
| 2642 } } // namespace v8::internal | 2644 } } // namespace v8::internal |
| OLD | NEW |