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

Side by Side Diff: src/heap/mark-compact.cc

Issue 440063002: Move ClearNonLiveReferences and friends into the gc. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months 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
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/objects.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/base/atomicops.h" 7 #include "src/base/atomicops.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/compilation-cache.h" 9 #include "src/compilation-cache.h"
10 #include "src/cpu-profiler.h" 10 #include "src/cpu-profiler.h"
(...skipping 2562 matching lines...) Expand 10 before | Expand all | Expand 10 after
2573 MarkBit map_mark) { 2573 MarkBit map_mark) {
2574 Object* potential_parent = map->GetBackPointer(); 2574 Object* potential_parent = map->GetBackPointer();
2575 if (!potential_parent->IsMap()) return; 2575 if (!potential_parent->IsMap()) return;
2576 Map* parent = Map::cast(potential_parent); 2576 Map* parent = Map::cast(potential_parent);
2577 2577
2578 // Follow back pointer, check whether we are dealing with a map transition 2578 // Follow back pointer, check whether we are dealing with a map transition
2579 // from a live map to a dead path and in case clear transitions of parent. 2579 // from a live map to a dead path and in case clear transitions of parent.
2580 bool current_is_alive = map_mark.Get(); 2580 bool current_is_alive = map_mark.Get();
2581 bool parent_is_alive = Marking::MarkBitFrom(parent).Get(); 2581 bool parent_is_alive = Marking::MarkBitFrom(parent).Get();
2582 if (!current_is_alive && parent_is_alive) { 2582 if (!current_is_alive && parent_is_alive) {
2583 parent->ClearNonLiveTransitions(heap()); 2583 ClearMapTransitions(parent);
2584 } 2584 }
2585 } 2585 }
2586 2586
2587 2587
2588 // Clear a possible back pointer in case the transition leads to a dead map.
2589 // Return true in case a back pointer has been cleared and false otherwise.
2590 bool MarkCompactCollector::ClearMapBackPointer(Map* target) {
2591 if (Marking::MarkBitFrom(target).Get()) return false;
2592 target->SetBackPointer(heap_->undefined_value(), SKIP_WRITE_BARRIER);
2593 return true;
2594 }
2595
2596
2597 void MarkCompactCollector::ClearMapTransitions(Map* map) {
2598 // If there are no transitions to be cleared, return.
2599 // TODO(verwaest) Should be an assert, otherwise back pointers are not
2600 // properly cleared.
2601 if (!map->HasTransitionArray()) return;
2602
2603 TransitionArray* t = map->transitions();
2604
2605 int transition_index = 0;
2606
2607 DescriptorArray* descriptors = map->instance_descriptors();
2608 bool descriptors_owner_died = false;
2609
2610 // Compact all live descriptors to the left.
2611 for (int i = 0; i < t->number_of_transitions(); ++i) {
2612 Map* target = t->GetTarget(i);
2613 if (ClearMapBackPointer(target)) {
2614 if (target->instance_descriptors() == descriptors) {
2615 descriptors_owner_died = true;
2616 }
2617 } else {
2618 if (i != transition_index) {
2619 Name* key = t->GetKey(i);
2620 t->SetKey(transition_index, key);
2621 Object** key_slot = t->GetKeySlot(transition_index);
2622 RecordSlot(key_slot, key_slot, key);
2623 // Target slots do not need to be recorded since maps are not compacted.
2624 t->SetTarget(transition_index, t->GetTarget(i));
2625 }
2626 transition_index++;
2627 }
2628 }
2629
2630 // If there are no transitions to be cleared, return.
2631 // TODO(verwaest) Should be an assert, otherwise back pointers are not
2632 // properly cleared.
2633 if (transition_index == t->number_of_transitions()) return;
2634
2635 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
2636
2637 if (descriptors_owner_died) {
2638 if (number_of_own_descriptors > 0) {
2639 TrimDescriptorArray(map, descriptors, number_of_own_descriptors);
2640 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors);
2641 map->set_owns_descriptors(true);
2642 } else {
2643 DCHECK(descriptors == heap_->empty_descriptor_array());
2644 }
2645 }
2646
2647 // Note that we never eliminate a transition array, though we might right-trim
2648 // such that number_of_transitions() == 0. If this assumption changes,
2649 // TransitionArray::CopyInsert() will need to deal with the case that a
2650 // transition array disappeared during GC.
2651 int trim = t->number_of_transitions() - transition_index;
2652 if (trim > 0) {
2653 heap_->RightTrimFixedArray<Heap::FROM_GC>(
2654 t, t->IsSimpleTransition() ? trim
2655 : trim * TransitionArray::kTransitionSize);
2656 }
2657 DCHECK(map->HasTransitionArray());
2658 }
2659
2660
2661 void MarkCompactCollector::TrimDescriptorArray(Map* map,
2662 DescriptorArray* descriptors,
2663 int number_of_own_descriptors) {
2664 int number_of_descriptors = descriptors->number_of_descriptors_storage();
2665 int to_trim = number_of_descriptors - number_of_own_descriptors;
2666 if (to_trim == 0) return;
2667
2668 heap_->RightTrimFixedArray<Heap::FROM_GC>(
2669 descriptors, to_trim * DescriptorArray::kDescriptorSize);
2670 descriptors->SetNumberOfDescriptors(number_of_own_descriptors);
2671
2672 if (descriptors->HasEnumCache()) TrimEnumCache(map, descriptors);
2673 descriptors->Sort();
2674 }
2675
2676
2677 void MarkCompactCollector::TrimEnumCache(Map* map,
2678 DescriptorArray* descriptors) {
2679 int live_enum = map->EnumLength();
2680 if (live_enum == kInvalidEnumCacheSentinel) {
2681 live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
2682 }
2683 if (live_enum == 0) return descriptors->ClearEnumCache();
2684
2685 FixedArray* enum_cache = descriptors->GetEnumCache();
2686
2687 int to_trim = enum_cache->length() - live_enum;
2688 if (to_trim <= 0) return;
2689 heap_->RightTrimFixedArray<Heap::FROM_GC>(descriptors->GetEnumCache(),
2690 to_trim);
2691
2692 if (!descriptors->HasEnumIndicesCache()) return;
2693 FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache();
2694 heap_->RightTrimFixedArray<Heap::FROM_GC>(enum_indices_cache, to_trim);
2695 }
2696
2697
2588 void MarkCompactCollector::ClearDependentICList(Object* head) { 2698 void MarkCompactCollector::ClearDependentICList(Object* head) {
2589 Object* current = head; 2699 Object* current = head;
2590 Object* undefined = heap()->undefined_value(); 2700 Object* undefined = heap()->undefined_value();
2591 while (current != undefined) { 2701 while (current != undefined) {
2592 Code* code = Code::cast(current); 2702 Code* code = Code::cast(current);
2593 if (IsMarked(code)) { 2703 if (IsMarked(code)) {
2594 DCHECK(code->is_weak_stub()); 2704 DCHECK(code->is_weak_stub());
2595 IC::InvalidateMaps(code); 2705 IC::InvalidateMaps(code);
2596 } 2706 }
2597 current = code->next_code_link(); 2707 current = code->next_code_link();
(...skipping 2084 matching lines...) Expand 10 before | Expand all | Expand 10 after
4682 SlotsBuffer* buffer = *buffer_address; 4792 SlotsBuffer* buffer = *buffer_address;
4683 while (buffer != NULL) { 4793 while (buffer != NULL) {
4684 SlotsBuffer* next_buffer = buffer->next(); 4794 SlotsBuffer* next_buffer = buffer->next();
4685 DeallocateBuffer(buffer); 4795 DeallocateBuffer(buffer);
4686 buffer = next_buffer; 4796 buffer = next_buffer;
4687 } 4797 }
4688 *buffer_address = NULL; 4798 *buffer_address = NULL;
4689 } 4799 }
4690 } 4800 }
4691 } // namespace v8::internal 4801 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698