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

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 1827 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 if (!code->CanDeoptAt(it.frame()->pc())) { 1838 if (!code->CanDeoptAt(it.frame()->pc())) {
1839 Code::BodyDescriptor::IterateBody(code, visitor); 1839 Code::BodyDescriptor::IterateBody(code, visitor);
1840 } 1840 }
1841 ProcessMarkingDeque(); 1841 ProcessMarkingDeque();
1842 return; 1842 return;
1843 } 1843 }
1844 } 1844 }
1845 } 1845 }
1846 1846
1847 1847
1848 bool ShouldRetainMap(Map* map, int age) {
1849 if (age == 0) {
1850 // The map has aged. Do not retain this map.
1851 return false;
1852 }
1853 Object* constructor = map->GetConstructor();
1854 if (!constructor->IsHeapObject() ||
1855 Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(constructor)))) {
1856 // The constructor is dead, no new objects with this map can
1857 // be created. Do not retain this map.
1858 return false;
1859 }
1860 return true;
1861 }
1862
1863
1864 void MarkCompactCollector::RetainMaps() {
1865 // Do not retain dead maps if flag disables it or there is
1866 // - memory pressure (reduce_memory_footprint_),
1867 // - GC is requested by tests or dev-tools (abort_incremental_marking_).
1868 bool map_retaining_is_disabled = heap()->ShouldReduceMemory() ||
1869 heap()->ShouldAbortIncrementalMarking() ||
1870 FLAG_retain_maps_for_n_gc == 0;
1871
1872 ArrayList* retained_maps = heap()->retained_maps();
1873 int length = retained_maps->Length();
1874 int new_length = 0;
1875 // The number_of_disposed_maps separates maps in the retained_maps
1876 // array that were created before and after context disposal.
1877 // We do not age and retain disposed maps to avoid memory leaks.
1878 int number_of_disposed_maps = heap()->number_of_disposed_maps_;
1879 int new_number_of_disposed_maps = 0;
1880 // This loop compacts the array by removing cleared weak cells,
1881 // ages and retains dead maps.
1882 for (int i = 0; i < length; i += 2) {
1883 DCHECK(retained_maps->Get(i)->IsWeakCell());
1884 WeakCell* cell = WeakCell::cast(retained_maps->Get(i));
1885 if (cell->cleared()) continue;
1886 int age = Smi::cast(retained_maps->Get(i + 1))->value();
1887 int new_age;
1888 Map* map = Map::cast(cell->value());
1889 MarkBit map_mark = Marking::MarkBitFrom(map);
1890 if (i >= number_of_disposed_maps && !map_retaining_is_disabled &&
1891 Marking::IsWhite(map_mark)) {
1892 if (ShouldRetainMap(map, age)) {
1893 MarkObject(map, map_mark);
1894 }
1895 Object* prototype = map->prototype();
1896 if (age > 0 && prototype->IsHeapObject() &&
1897 Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(prototype)))) {
1898 // The prototype is not marked, age the map.
1899 new_age = age - 1;
1900 } else {
1901 // The prototype and the constructor are marked, this map keeps only
1902 // transition tree alive, not JSObjects. Do not age the map.
1903 new_age = age;
1904 }
1905 } else {
1906 new_age = FLAG_retain_maps_for_n_gc;
1907 }
1908 // Compact the array and update the age.
1909 if (i != new_length) {
1910 retained_maps->Set(new_length, cell);
1911 Object** slot = retained_maps->Slot(new_length);
1912 RecordSlot(retained_maps, slot, cell);
1913 retained_maps->Set(new_length + 1, Smi::FromInt(new_age));
1914 } else if (new_age != age) {
1915 retained_maps->Set(new_length + 1, Smi::FromInt(new_age));
1916 }
1917 if (i < number_of_disposed_maps) {
1918 new_number_of_disposed_maps++;
1919 }
1920 new_length += 2;
1921 }
1922 heap()->number_of_disposed_maps_ = new_number_of_disposed_maps;
1923 Object* undefined = heap()->undefined_value();
1924 for (int i = new_length; i < length; i++) {
1925 retained_maps->Clear(i, undefined);
1926 }
1927 if (new_length != length) retained_maps->SetLength(new_length);
1928 ProcessMarkingDeque();
1929 }
1930
1931
1932 void MarkCompactCollector::EnsureMarkingDequeIsReserved() { 1848 void MarkCompactCollector::EnsureMarkingDequeIsReserved() {
1933 DCHECK(!marking_deque_.in_use()); 1849 DCHECK(!marking_deque_.in_use());
1934 if (marking_deque_memory_ == NULL) { 1850 if (marking_deque_memory_ == NULL) {
1935 marking_deque_memory_ = new base::VirtualMemory(kMaxMarkingDequeSize); 1851 marking_deque_memory_ = new base::VirtualMemory(kMaxMarkingDequeSize);
1936 marking_deque_memory_committed_ = 0; 1852 marking_deque_memory_committed_ = 0;
1937 } 1853 }
1938 if (marking_deque_memory_ == NULL) { 1854 if (marking_deque_memory_ == NULL) {
1939 V8::FatalProcessOutOfMemory("EnsureMarkingDequeIsReserved"); 1855 V8::FatalProcessOutOfMemory("EnsureMarkingDequeIsReserved");
1940 } 1856 }
1941 } 1857 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2055 { 1971 {
2056 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK_ROOT); 1972 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK_ROOT);
2057 MarkRoots(&root_visitor); 1973 MarkRoots(&root_visitor);
2058 } 1974 }
2059 1975
2060 { 1976 {
2061 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK_TOPOPT); 1977 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK_TOPOPT);
2062 ProcessTopOptimizedFrame(&root_visitor); 1978 ProcessTopOptimizedFrame(&root_visitor);
2063 } 1979 }
2064 1980
2065 // Retaining dying maps should happen before or during ephemeral marking
2066 // because a map could keep the key of an ephemeron alive. Note that map
2067 // aging is imprecise: maps that are kept alive only by ephemerons will age.
2068 {
2069 GCTracer::Scope gc_scope(heap()->tracer(),
2070 GCTracer::Scope::MC_MARK_RETAIN_MAPS);
2071 RetainMaps();
2072 }
2073
2074 { 1981 {
2075 GCTracer::Scope gc_scope(heap()->tracer(), 1982 GCTracer::Scope gc_scope(heap()->tracer(),
2076 GCTracer::Scope::MC_MARK_WEAK_CLOSURE); 1983 GCTracer::Scope::MC_MARK_WEAK_CLOSURE);
2077 1984
2078 // The objects reachable from the roots are marked, yet unreachable 1985 // The objects reachable from the roots are marked, yet unreachable
2079 // objects are unmarked. Mark objects reachable due to host 1986 // objects are unmarked. Mark objects reachable due to host
2080 // application specific logic or through Harmony weak maps. 1987 // application specific logic or through Harmony weak maps.
2081 ProcessEphemeralMarking(&root_visitor, false); 1988 ProcessEphemeralMarking(&root_visitor, false);
2082 1989
2083 // The objects reachable from the roots, weak maps or object groups 1990 // The objects reachable from the roots, weak maps or object groups
(...skipping 1983 matching lines...) Expand 10 before | Expand all | Expand 10 after
4067 MarkBit mark_bit = Marking::MarkBitFrom(host); 3974 MarkBit mark_bit = Marking::MarkBitFrom(host);
4068 if (Marking::IsBlack(mark_bit)) { 3975 if (Marking::IsBlack(mark_bit)) {
4069 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); 3976 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host);
4070 RecordRelocSlot(&rinfo, target); 3977 RecordRelocSlot(&rinfo, target);
4071 } 3978 }
4072 } 3979 }
4073 } 3980 }
4074 3981
4075 } // namespace internal 3982 } // namespace internal
4076 } // namespace v8 3983 } // 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