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

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

Issue 1481953002: Move map retaining to finalization of incremental marking. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/objects.h » ('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/heap/mark-compact.h" 5 #include "src/heap/mark-compact.h"
6 6
7 #include "src/base/atomicops.h" 7 #include "src/base/atomicops.h"
8 #include "src/base/bits.h" 8 #include "src/base/bits.h"
9 #include "src/base/sys-info.h" 9 #include "src/base/sys-info.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 1879 matching lines...) Expand 10 before | Expand all | Expand 10 after
1890 if (!code->CanDeoptAt(it.frame()->pc())) { 1890 if (!code->CanDeoptAt(it.frame()->pc())) {
1891 Code::BodyDescriptor::IterateBody(code, visitor); 1891 Code::BodyDescriptor::IterateBody(code, visitor);
1892 } 1892 }
1893 ProcessMarkingDeque(); 1893 ProcessMarkingDeque();
1894 return; 1894 return;
1895 } 1895 }
1896 } 1896 }
1897 } 1897 }
1898 1898
1899 1899
1900 bool ShouldRetainMap(Map* map, int age) {
1901 if (age == 0) {
1902 // The map has aged. Do not retain this map.
1903 return false;
1904 }
1905 Object* constructor = map->GetConstructor();
1906 if (!constructor->IsHeapObject() ||
1907 Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(constructor)))) {
1908 // The constructor is dead, no new objects with this map can
1909 // be created. Do not retain this map.
1910 return false;
1911 }
1912 return true;
1913 }
1914
1915
1916 void MarkCompactCollector::RetainMaps() {
1917 // Do not retain dead maps if flag disables it or there is
ulan 2015/11/30 09:32:24 This function moved to heap and incremental-markin
1918 // - memory pressure (reduce_memory_footprint_),
1919 // - GC is requested by tests or dev-tools (abort_incremental_marking_).
1920 bool map_retaining_is_disabled = heap()->ShouldReduceMemory() ||
1921 heap()->ShouldAbortIncrementalMarking() ||
1922 FLAG_retain_maps_for_n_gc == 0;
1923
1924 ArrayList* retained_maps = heap()->retained_maps();
1925 int length = retained_maps->Length();
1926 int new_length = 0;
1927 // The number_of_disposed_maps separates maps in the retained_maps
1928 // array that were created before and after context disposal.
1929 // We do not age and retain disposed maps to avoid memory leaks.
1930 int number_of_disposed_maps = heap()->number_of_disposed_maps_;
1931 int new_number_of_disposed_maps = 0;
1932 // This loop compacts the array by removing cleared weak cells,
1933 // ages and retains dead maps.
1934 for (int i = 0; i < length; i += 2) {
1935 DCHECK(retained_maps->Get(i)->IsWeakCell());
1936 WeakCell* cell = WeakCell::cast(retained_maps->Get(i));
1937 if (cell->cleared()) continue;
1938 int age = Smi::cast(retained_maps->Get(i + 1))->value();
1939 int new_age;
1940 Map* map = Map::cast(cell->value());
1941 MarkBit map_mark = Marking::MarkBitFrom(map);
1942 if (i >= number_of_disposed_maps && !map_retaining_is_disabled &&
1943 Marking::IsWhite(map_mark)) {
1944 if (ShouldRetainMap(map, age)) {
1945 MarkObject(map, map_mark);
1946 }
1947 Object* prototype = map->prototype();
1948 if (age > 0 && prototype->IsHeapObject() &&
1949 Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(prototype)))) {
1950 // The prototype is not marked, age the map.
1951 new_age = age - 1;
1952 } else {
1953 // The prototype and the constructor are marked, this map keeps only
1954 // transition tree alive, not JSObjects. Do not age the map.
1955 new_age = age;
1956 }
1957 } else {
1958 new_age = FLAG_retain_maps_for_n_gc;
1959 }
1960 // Compact the array and update the age.
1961 if (i != new_length) {
1962 retained_maps->Set(new_length, cell);
1963 Object** slot = retained_maps->Slot(new_length);
1964 RecordSlot(retained_maps, slot, cell);
1965 retained_maps->Set(new_length + 1, Smi::FromInt(new_age));
1966 } else if (new_age != age) {
1967 retained_maps->Set(new_length + 1, Smi::FromInt(new_age));
1968 }
1969 if (i < number_of_disposed_maps) {
1970 new_number_of_disposed_maps++;
1971 }
1972 new_length += 2;
1973 }
1974 heap()->number_of_disposed_maps_ = new_number_of_disposed_maps;
1975 Object* undefined = heap()->undefined_value();
1976 for (int i = new_length; i < length; i++) {
1977 retained_maps->Clear(i, undefined);
1978 }
1979 if (new_length != length) retained_maps->SetLength(new_length);
1980 ProcessMarkingDeque();
1981 }
1982
1983
1984 DependentCode* MarkCompactCollector::DependentCodeListFromNonLiveMaps() { 1900 DependentCode* MarkCompactCollector::DependentCodeListFromNonLiveMaps() {
1985 GCTracer::Scope gc_scope(heap()->tracer(), 1901 GCTracer::Scope gc_scope(heap()->tracer(),
1986 GCTracer::Scope::MC_EXTRACT_DEPENDENT_CODE); 1902 GCTracer::Scope::MC_EXTRACT_DEPENDENT_CODE);
1987 ArrayList* retained_maps = heap()->retained_maps(); 1903 ArrayList* retained_maps = heap()->retained_maps();
1988 int length = retained_maps->Length(); 1904 int length = retained_maps->Length();
1989 DependentCode* head = DependentCode::cast(heap()->empty_fixed_array()); 1905 DependentCode* head = DependentCode::cast(heap()->empty_fixed_array());
1990 for (int i = 0; i < length; i += 2) { 1906 for (int i = 0; i < length; i += 2) {
1991 DCHECK(retained_maps->Get(i)->IsWeakCell()); 1907 DCHECK(retained_maps->Get(i)->IsWeakCell());
1992 WeakCell* cell = WeakCell::cast(retained_maps->Get(i)); 1908 WeakCell* cell = WeakCell::cast(retained_maps->Get(i));
1993 DCHECK(!cell->cleared()); 1909 if (cell->cleared()) continue;
1994 Map* map = Map::cast(cell->value()); 1910 Map* map = Map::cast(cell->value());
1995 MarkBit map_mark = Marking::MarkBitFrom(map); 1911 MarkBit map_mark = Marking::MarkBitFrom(map);
1996 if (Marking::IsWhite(map_mark)) { 1912 if (Marking::IsWhite(map_mark)) {
1997 DependentCode* candidate = map->dependent_code(); 1913 DependentCode* candidate = map->dependent_code();
1998 // We rely on the fact that the weak code group comes first. 1914 // We rely on the fact that the weak code group comes first.
1999 STATIC_ASSERT(DependentCode::kWeakCodeGroup == 0); 1915 STATIC_ASSERT(DependentCode::kWeakCodeGroup == 0);
2000 if (candidate->length() > 0 && 1916 if (candidate->length() > 0 &&
2001 candidate->group() == DependentCode::kWeakCodeGroup) { 1917 candidate->group() == DependentCode::kWeakCodeGroup) {
2002 candidate->set_next_link(head); 1918 candidate->set_next_link(head);
2003 head = candidate; 1919 head = candidate;
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 { 2050 {
2135 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK_ROOT); 2051 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK_ROOT);
2136 MarkRoots(&root_visitor); 2052 MarkRoots(&root_visitor);
2137 } 2053 }
2138 2054
2139 { 2055 {
2140 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK_TOPOPT); 2056 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK_TOPOPT);
2141 ProcessTopOptimizedFrame(&root_visitor); 2057 ProcessTopOptimizedFrame(&root_visitor);
2142 } 2058 }
2143 2059
2144 // Retaining dying maps should happen before or during ephemeral marking
2145 // because a map could keep the key of an ephemeron alive. Note that map
2146 // aging is imprecise: maps that are kept alive only by ephemerons will age.
2147 {
2148 GCTracer::Scope gc_scope(heap()->tracer(),
2149 GCTracer::Scope::MC_MARK_RETAIN_MAPS);
Hannes Payer (out of office) 2015/12/01 10:00:52 Remove this counter from the tracer, it is not use
2150 RetainMaps();
2151 }
2152
2153 { 2060 {
2154 GCTracer::Scope gc_scope(heap()->tracer(), 2061 GCTracer::Scope gc_scope(heap()->tracer(),
2155 GCTracer::Scope::MC_MARK_WEAK_CLOSURE); 2062 GCTracer::Scope::MC_MARK_WEAK_CLOSURE);
2156 2063
2157 // The objects reachable from the roots are marked, yet unreachable 2064 // The objects reachable from the roots are marked, yet unreachable
2158 // objects are unmarked. Mark objects reachable due to host 2065 // objects are unmarked. Mark objects reachable due to host
2159 // application specific logic or through Harmony weak maps. 2066 // application specific logic or through Harmony weak maps.
2160 ProcessEphemeralMarking(&root_visitor, false); 2067 ProcessEphemeralMarking(&root_visitor, false);
2161 2068
2162 // The objects reachable from the roots, weak maps or object groups 2069 // The objects reachable from the roots, weak maps or object groups
(...skipping 2005 matching lines...) Expand 10 before | Expand all | Expand 10 after
4168 MarkBit mark_bit = Marking::MarkBitFrom(host); 4075 MarkBit mark_bit = Marking::MarkBitFrom(host);
4169 if (Marking::IsBlack(mark_bit)) { 4076 if (Marking::IsBlack(mark_bit)) {
4170 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); 4077 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host);
4171 RecordRelocSlot(&rinfo, target); 4078 RecordRelocSlot(&rinfo, target);
4172 } 4079 }
4173 } 4080 }
4174 } 4081 }
4175 4082
4176 } // namespace internal 4083 } // namespace internal
4177 } // namespace v8 4084 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698