Optimize MarkCompactCollector::ClearNonLiveReferences.

This splits the work to be done for dead and life maps
and avoids unnecessary operations in the hot loop.

Results for v8.infinite_scroll:

Before:
nonlive_refs
  len: 93
  min: 0.0
  max: 6.3
  avg: 1.35268817204
  [0,5[: 91
  [5,10[: 2

After:
nonlive_refs
  len: 91
  min: 0.0
  max: 4.2
  avg: 0.968131868132
  [0,5[: 91

BUG=chromium:554488
LOG=no

Review URL: https://codereview.chromium.org/1441633002

Cr-Commit-Position: refs/heads/master@{#32042}
This commit is contained in:
ulan 2015-11-17 05:29:04 -08:00 committed by Commit bot
parent a2a2ebe606
commit ed357f9696
2 changed files with 9 additions and 11 deletions

View File

@ -2202,14 +2202,13 @@ void MarkCompactCollector::ClearNonLiveReferences() {
for (HeapObject* obj = map_iterator.Next(); obj != NULL;
obj = map_iterator.Next()) {
Map* map = Map::cast(obj);
if (!map->CanTransition()) continue;
MarkBit map_mark = Marking::MarkBitFrom(map);
ClearNonLivePrototypeTransitions(map);
ClearNonLiveMapTransitions(map, map_mark);
if (Marking::IsWhite(map_mark)) {
bool alive = Marking::IsBlackOrGrey(map_mark);
if (alive) {
ClearNonLivePrototypeTransitions(map);
} else {
ClearNonLiveMapTransitions(map);
have_code_to_deoptimize_ |=
map->dependent_code()->MarkCodeForDeoptimization(
isolate(), DependentCode::kWeakCodeGroup);
@ -2271,17 +2270,16 @@ void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) {
}
void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map,
MarkBit map_mark) {
void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map) {
Object* potential_parent = map->GetBackPointer();
if (!potential_parent->IsMap()) return;
Map* parent = Map::cast(potential_parent);
// Follow back pointer, check whether we are dealing with a map transition
// from a live map to a dead path and in case clear transitions of parent.
bool current_is_alive = Marking::IsBlackOrGrey(map_mark);
DCHECK(!Marking::IsBlackOrGrey(Marking::MarkBitFrom(map)));
bool parent_is_alive = Marking::IsBlackOrGrey(Marking::MarkBitFrom(parent));
if (!current_is_alive && parent_is_alive) {
if (parent_is_alive) {
ClearMapTransitions(parent, map);
}
}

View File

@ -654,7 +654,7 @@ class MarkCompactCollector {
// We replace them with a null descriptor, with the same key.
void ClearNonLiveReferences();
void ClearNonLivePrototypeTransitions(Map* map);
void ClearNonLiveMapTransitions(Map* map, MarkBit map_mark);
void ClearNonLiveMapTransitions(Map* map);
void ClearMapTransitions(Map* map, Map* dead_transition);
bool ClearMapBackPointer(Map* map);
void TrimDescriptorArray(Map* map, DescriptorArray* descriptors,