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

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

Issue 10816005: Swapped transition array and descriptor array. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments, and updated additional code comments. Created 8 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1831 matching lines...) Expand 10 before | Expand all | Expand 10 after
1842 1842
1843 1843
1844 // Force instantiation of template instances. 1844 // Force instantiation of template instances.
1845 template void Marker<IncrementalMarking>::MarkMapContents(Map* map); 1845 template void Marker<IncrementalMarking>::MarkMapContents(Map* map);
1846 template void Marker<MarkCompactCollector>::MarkMapContents(Map* map); 1846 template void Marker<MarkCompactCollector>::MarkMapContents(Map* map);
1847 1847
1848 1848
1849 template <class T> 1849 template <class T>
1850 void Marker<T>::MarkMapContents(Map* map) { 1850 void Marker<T>::MarkMapContents(Map* map) {
1851 // Make sure that the back pointer stored either in the map itself or inside 1851 // Make sure that the back pointer stored either in the map itself or inside
1852 // its prototype transitions array is marked. Treat pointers in the descriptor 1852 // its transitions array is marked. Treat pointers in the transitions array as
1853 // array as weak and also mark that array to prevent visiting it later. 1853 // weak and also mark that array to prevent visiting it later.
1854 base_marker()->MarkObjectAndPush(HeapObject::cast(map->GetBackPointer())); 1854 base_marker()->MarkObjectAndPush(HeapObject::cast(map->GetBackPointer()));
1855 1855
1856 Object** descriptor_array_slot = 1856 Object** transitions_slot =
1857 HeapObject::RawField(map, Map::kInstanceDescriptorsOrBackPointerOffset); 1857 HeapObject::RawField(map, Map::kTransitionsOrBackPointerOffset);
1858 Object* descriptor_array = *descriptor_array_slot; 1858 Object* transitions = *transitions_slot;
1859 if (descriptor_array->IsDescriptorArray()) { 1859 if (transitions->IsTransitionArray()) {
1860 MarkDescriptorArray(reinterpret_cast<DescriptorArray*>(descriptor_array)); 1860 MarkTransitionArray(reinterpret_cast<TransitionArray*>(transitions));
1861 } else { 1861 } else {
1862 // Already marked by marking map->GetBackPointer(). 1862 // Already marked by marking map->GetBackPointer().
1863 ASSERT(descriptor_array->IsMap() || descriptor_array->IsUndefined()); 1863 ASSERT(transitions->IsMap() || transitions->IsUndefined());
1864 } 1864 }
1865 1865
1866 // Mark the Object* fields of the Map. Since the descriptor array has been 1866 // Mark the Object* fields of the Map. Since the transitions array has been
1867 // marked already, it is fine that one of these fields contains a pointer 1867 // marked already, it is fine that one of these fields contains a pointer to
1868 // to it. But make sure to skip back pointer. 1868 // it.
1869 STATIC_ASSERT(Map::kPointerFieldsEndOffset ==
1870 Map::kBitField3Offset + kPointerSize);
1871 Object** start_slot = 1869 Object** start_slot =
1872 HeapObject::RawField(map, Map::kPointerFieldsBeginOffset); 1870 HeapObject::RawField(map, Map::kPointerFieldsBeginOffset);
1873 Object** end_slot = HeapObject::RawField(map, Map::kBitField3Offset); 1871 Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset);
1874 for (Object** slot = start_slot; slot < end_slot; slot++) { 1872 for (Object** slot = start_slot; slot < end_slot; slot++) {
1875 Object* obj = *slot; 1873 Object* obj = *slot;
1876 if (!obj->NonFailureIsHeapObject()) continue; 1874 if (!obj->NonFailureIsHeapObject()) continue;
1877 mark_compact_collector()->RecordSlot(start_slot, slot, obj); 1875 mark_compact_collector()->RecordSlot(start_slot, slot, obj);
1878 base_marker()->MarkObjectAndPush(reinterpret_cast<HeapObject*>(obj)); 1876 base_marker()->MarkObjectAndPush(reinterpret_cast<HeapObject*>(obj));
1879 } 1877 }
1880 } 1878 }
1881 1879
1882 1880
1883 template <class T> 1881 template <class T>
1884 void Marker<T>::MarkDescriptorArray(DescriptorArray* descriptors) {
1885 // Empty descriptor array is marked as a root before any maps are marked.
1886 ASSERT(descriptors != descriptors->GetHeap()->empty_descriptor_array());
1887
1888 if (!base_marker()->MarkObjectWithoutPush(descriptors)) return;
1889 Object** descriptor_start = descriptors->data_start();
1890
1891 // Since the descriptor array itself is not pushed for scanning, all fields
1892 // that point to objects manually have to be pushed, marked, and their slots
1893 // recorded.
1894 if (descriptors->HasEnumCache()) {
1895 Object** enum_cache_slot = descriptors->GetEnumCacheSlot();
1896 Object* enum_cache = *enum_cache_slot;
1897 base_marker()->MarkObjectAndPush(
1898 reinterpret_cast<HeapObject*>(enum_cache));
1899 mark_compact_collector()->RecordSlot(descriptor_start,
1900 enum_cache_slot,
1901 enum_cache);
1902 }
1903
1904 if (descriptors->HasTransitionArray()) {
1905 Object** transitions_slot = descriptors->GetTransitionsSlot();
1906 Object* transitions = *transitions_slot;
1907 mark_compact_collector()->RecordSlot(descriptor_start,
1908 transitions_slot,
1909 transitions);
1910 MarkTransitionArray(reinterpret_cast<TransitionArray*>(transitions));
1911 }
1912
1913 // If the descriptor contains a transition (value is a Map), we don't mark the
1914 // value as live. It might be removed by ClearNonLiveTransitions later.
1915 for (int i = 0; i < descriptors->number_of_descriptors(); ++i) {
1916 Object** key_slot = descriptors->GetKeySlot(i);
1917 Object* key = *key_slot;
1918 if (key->IsHeapObject()) {
1919 base_marker()->MarkObjectAndPush(HeapObject::cast(key));
1920 mark_compact_collector()->RecordSlot(descriptor_start, key_slot, key);
1921 }
1922
1923 Object** value_slot = descriptors->GetValueSlot(i);
1924 if (!(*value_slot)->IsHeapObject()) continue;
1925 HeapObject* value = HeapObject::cast(*value_slot);
1926
1927 mark_compact_collector()->RecordSlot(descriptor_start,
1928 value_slot,
1929 value);
1930
1931 PropertyDetails details(descriptors->GetDetails(i));
1932
1933 switch (details.type()) {
1934 case NORMAL:
1935 case FIELD:
1936 case CONSTANT_FUNCTION:
1937 case HANDLER:
1938 case INTERCEPTOR:
1939 case CALLBACKS:
1940 base_marker()->MarkObjectAndPush(value);
1941 break;
1942 case TRANSITION:
1943 case NONEXISTENT:
1944 UNREACHABLE();
1945 break;
1946 }
1947 }
1948 }
1949
1950 template <class T>
1951 void Marker<T>::MarkTransitionArray(TransitionArray* transitions) { 1882 void Marker<T>::MarkTransitionArray(TransitionArray* transitions) {
1952 if (!base_marker()->MarkObjectWithoutPush(transitions)) return; 1883 if (!base_marker()->MarkObjectWithoutPush(transitions)) return;
1953 Object** transitions_start = transitions->data_start(); 1884 Object** transitions_start = transitions->data_start();
1954 1885
1886 DescriptorArray* descriptors = transitions->descriptors();
1887 base_marker()->MarkObjectAndPush(descriptors);
1888 mark_compact_collector()->RecordSlot(
1889 transitions_start, transitions->GetDescriptorsSlot(), descriptors);
1890
1955 if (transitions->HasPrototypeTransitions()) { 1891 if (transitions->HasPrototypeTransitions()) {
1956 // Mark prototype transitions array but don't push it into marking stack. 1892 // Mark prototype transitions array but don't push it into marking stack.
1957 // This will make references from it weak. We will clean dead prototype 1893 // This will make references from it weak. We will clean dead prototype
1958 // transitions in ClearNonLiveTransitions. 1894 // transitions in ClearNonLiveTransitions.
1959 Object** proto_trans_slot = transitions->GetPrototypeTransitionsSlot(); 1895 Object** proto_trans_slot = transitions->GetPrototypeTransitionsSlot();
1960 HeapObject* prototype_transitions = HeapObject::cast(*proto_trans_slot); 1896 HeapObject* prototype_transitions = HeapObject::cast(*proto_trans_slot);
1961 base_marker()->MarkObjectWithoutPush(prototype_transitions); 1897 base_marker()->MarkObjectWithoutPush(prototype_transitions);
1962 mark_compact_collector()->RecordSlot( 1898 mark_compact_collector()->RecordSlot(
1963 transitions_start, proto_trans_slot, prototype_transitions); 1899 transitions_start, proto_trans_slot, prototype_transitions);
1964 } 1900 }
(...skipping 2184 matching lines...) Expand 10 before | Expand all | Expand 10 after
4149 while (buffer != NULL) { 4085 while (buffer != NULL) {
4150 SlotsBuffer* next_buffer = buffer->next(); 4086 SlotsBuffer* next_buffer = buffer->next();
4151 DeallocateBuffer(buffer); 4087 DeallocateBuffer(buffer);
4152 buffer = next_buffer; 4088 buffer = next_buffer;
4153 } 4089 }
4154 *buffer_address = NULL; 4090 *buffer_address = NULL;
4155 } 4091 }
4156 4092
4157 4093
4158 } } // namespace v8::internal 4094 } } // namespace v8::internal
OLDNEW
« src/bootstrapper.cc ('K') | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698