OLD | NEW |
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 1805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1816 } | 1816 } |
1817 | 1817 |
1818 | 1818 |
1819 // Force instantiation of template instances. | 1819 // Force instantiation of template instances. |
1820 template void Marker<IncrementalMarking>::MarkMapContents(Map* map); | 1820 template void Marker<IncrementalMarking>::MarkMapContents(Map* map); |
1821 template void Marker<MarkCompactCollector>::MarkMapContents(Map* map); | 1821 template void Marker<MarkCompactCollector>::MarkMapContents(Map* map); |
1822 | 1822 |
1823 | 1823 |
1824 template <class T> | 1824 template <class T> |
1825 void Marker<T>::MarkMapContents(Map* map) { | 1825 void Marker<T>::MarkMapContents(Map* map) { |
1826 // Mark prototype transitions array but don't push it into marking stack. | |
1827 // This will make references from it weak. We will clean dead prototype | |
1828 // transitions in ClearNonLiveTransitions. | |
1829 Object** proto_trans_slot = | |
1830 HeapObject::RawField(map, Map::kPrototypeTransitionsOrBackPointerOffset); | |
1831 HeapObject* prototype_transitions = HeapObject::cast(*proto_trans_slot); | |
1832 if (prototype_transitions->IsFixedArray()) { | |
1833 mark_compact_collector()->RecordSlot(proto_trans_slot, | |
1834 proto_trans_slot, | |
1835 prototype_transitions); | |
1836 MarkBit mark = Marking::MarkBitFrom(prototype_transitions); | |
1837 if (!mark.Get()) { | |
1838 mark.Set(); | |
1839 MemoryChunk::IncrementLiveBytesFromGC(prototype_transitions->address(), | |
1840 prototype_transitions->Size()); | |
1841 } | |
1842 } | |
1843 | |
1844 // Make sure that the back pointer stored either in the map itself or inside | 1826 // Make sure that the back pointer stored either in the map itself or inside |
1845 // its prototype transitions array is marked. Treat pointers in the descriptor | 1827 // its prototype transitions array is marked. Treat pointers in the descriptor |
1846 // array as weak and also mark that array to prevent visiting it later. | 1828 // array as weak and also mark that array to prevent visiting it later. |
1847 base_marker()->MarkObjectAndPush(HeapObject::cast(map->GetBackPointer())); | 1829 base_marker()->MarkObjectAndPush(HeapObject::cast(map->GetBackPointer())); |
1848 | 1830 |
1849 Object** descriptor_array_slot = | 1831 Object** descriptor_array_slot = |
1850 HeapObject::RawField(map, Map::kInstanceDescriptorsOrBitField3Offset); | 1832 HeapObject::RawField(map, Map::kInstanceDescriptorsOrBitField3Offset); |
1851 Object* descriptor_array = *descriptor_array_slot; | 1833 Object* descriptor_array = *descriptor_array_slot; |
1852 if (!descriptor_array->IsSmi()) { | 1834 if (!descriptor_array->IsSmi()) { |
1853 MarkDescriptorArray(reinterpret_cast<DescriptorArray*>(descriptor_array)); | 1835 MarkDescriptorArray(reinterpret_cast<DescriptorArray*>(descriptor_array)); |
1854 } | 1836 } |
1855 | 1837 |
1856 // Mark the Object* fields of the Map. Since the descriptor array has been | 1838 // Mark the Object* fields of the Map. Since the descriptor array has been |
1857 // marked already, it is fine that one of these fields contains a pointer | 1839 // marked already, it is fine that one of these fields contains a pointer |
1858 // to it. But make sure to skip back pointer and prototype transitions. | 1840 // to it. But make sure to skip back pointer. |
1859 STATIC_ASSERT(Map::kPointerFieldsEndOffset == | 1841 STATIC_ASSERT(Map::kPointerFieldsEndOffset == |
1860 Map::kPrototypeTransitionsOrBackPointerOffset + kPointerSize); | 1842 Map::kBackPointerOffset + kPointerSize); |
1861 Object** start_slot = HeapObject::RawField( | 1843 Object** start_slot = |
1862 map, Map::kPointerFieldsBeginOffset); | 1844 HeapObject::RawField(map, Map::kPointerFieldsBeginOffset); |
1863 Object** end_slot = HeapObject::RawField( | 1845 Object** end_slot = HeapObject::RawField(map, Map::kBackPointerOffset); |
1864 map, Map::kPrototypeTransitionsOrBackPointerOffset); | |
1865 for (Object** slot = start_slot; slot < end_slot; slot++) { | 1846 for (Object** slot = start_slot; slot < end_slot; slot++) { |
1866 Object* obj = *slot; | 1847 Object* obj = *slot; |
1867 if (!obj->NonFailureIsHeapObject()) continue; | 1848 if (!obj->NonFailureIsHeapObject()) continue; |
1868 mark_compact_collector()->RecordSlot(start_slot, slot, obj); | 1849 mark_compact_collector()->RecordSlot(start_slot, slot, obj); |
1869 base_marker()->MarkObjectAndPush(reinterpret_cast<HeapObject*>(obj)); | 1850 base_marker()->MarkObjectAndPush(reinterpret_cast<HeapObject*>(obj)); |
1870 } | 1851 } |
1871 } | 1852 } |
1872 | 1853 |
1873 | 1854 |
1874 template <class T> | 1855 template <class T> |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1950 void Marker<T>::MarkTransitionArray(TransitionArray* transitions) { | 1931 void Marker<T>::MarkTransitionArray(TransitionArray* transitions) { |
1951 if (!base_marker()->MarkObjectWithoutPush(transitions)) return; | 1932 if (!base_marker()->MarkObjectWithoutPush(transitions)) return; |
1952 Object** transitions_start = transitions->data_start(); | 1933 Object** transitions_start = transitions->data_start(); |
1953 | 1934 |
1954 if (transitions->HasElementsTransition()) { | 1935 if (transitions->HasElementsTransition()) { |
1955 mark_compact_collector()->RecordSlot(transitions_start, | 1936 mark_compact_collector()->RecordSlot(transitions_start, |
1956 transitions->GetElementsSlot(), | 1937 transitions->GetElementsSlot(), |
1957 transitions->elements_transition()); | 1938 transitions->elements_transition()); |
1958 } | 1939 } |
1959 | 1940 |
| 1941 if (transitions->HasPrototypeTransitions()) { |
| 1942 // Mark prototype transitions array but don't push it into marking stack. |
| 1943 // This will make references from it weak. We will clean dead prototype |
| 1944 // transitions in ClearNonLiveTransitions. |
| 1945 Object** proto_trans_slot = transitions->GetPrototypeTransitionsSlot(); |
| 1946 HeapObject* prototype_transitions = HeapObject::cast(*proto_trans_slot); |
| 1947 base_marker()->MarkObjectWithoutPush(prototype_transitions); |
| 1948 mark_compact_collector()->RecordSlot( |
| 1949 transitions_start, proto_trans_slot, prototype_transitions); |
| 1950 } |
| 1951 |
1960 for (int i = 0; i < transitions->number_of_transitions(); ++i) { | 1952 for (int i = 0; i < transitions->number_of_transitions(); ++i) { |
1961 Object** key_slot = transitions->GetKeySlot(i); | 1953 Object** key_slot = transitions->GetKeySlot(i); |
1962 Object* key = *key_slot; | 1954 Object* key = *key_slot; |
1963 if (key->IsHeapObject()) { | 1955 if (key->IsHeapObject()) { |
1964 base_marker()->MarkObjectAndPush(HeapObject::cast(key)); | 1956 base_marker()->MarkObjectAndPush(HeapObject::cast(key)); |
1965 mark_compact_collector()->RecordSlot(transitions_start, key_slot, key); | 1957 mark_compact_collector()->RecordSlot(transitions_start, key_slot, key); |
1966 } | 1958 } |
1967 | 1959 |
1968 Object** value_slot = transitions->GetValueSlot(i); | 1960 Object** value_slot = transitions->GetValueSlot(i); |
1969 if (!(*value_slot)->IsHeapObject()) continue; | 1961 if (!(*value_slot)->IsHeapObject()) continue; |
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2538 } | 2530 } |
2539 | 2531 |
2540 ClearNonLivePrototypeTransitions(map); | 2532 ClearNonLivePrototypeTransitions(map); |
2541 ClearNonLiveMapTransitions(map, map_mark); | 2533 ClearNonLiveMapTransitions(map, map_mark); |
2542 } | 2534 } |
2543 } | 2535 } |
2544 | 2536 |
2545 | 2537 |
2546 void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) { | 2538 void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) { |
2547 int number_of_transitions = map->NumberOfProtoTransitions(); | 2539 int number_of_transitions = map->NumberOfProtoTransitions(); |
2548 FixedArray* prototype_transitions = map->prototype_transitions(); | 2540 FixedArray* prototype_transitions = map->GetPrototypeTransitions(); |
2549 | 2541 |
2550 int new_number_of_transitions = 0; | 2542 int new_number_of_transitions = 0; |
2551 const int header = Map::kProtoTransitionHeaderSize; | 2543 const int header = Map::kProtoTransitionHeaderSize; |
2552 const int proto_offset = header + Map::kProtoTransitionPrototypeOffset; | 2544 const int proto_offset = header + Map::kProtoTransitionPrototypeOffset; |
2553 const int map_offset = header + Map::kProtoTransitionMapOffset; | 2545 const int map_offset = header + Map::kProtoTransitionMapOffset; |
2554 const int step = Map::kProtoTransitionElementsPerEntry; | 2546 const int step = Map::kProtoTransitionElementsPerEntry; |
2555 for (int i = 0; i < number_of_transitions; i++) { | 2547 for (int i = 0; i < number_of_transitions; i++) { |
2556 Object* prototype = prototype_transitions->get(proto_offset + i * step); | 2548 Object* prototype = prototype_transitions->get(proto_offset + i * step); |
2557 Object* cached_map = prototype_transitions->get(map_offset + i * step); | 2549 Object* cached_map = prototype_transitions->get(map_offset + i * step); |
2558 if (IsMarked(prototype) && IsMarked(cached_map)) { | 2550 if (IsMarked(prototype) && IsMarked(cached_map)) { |
(...skipping 1601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4160 while (buffer != NULL) { | 4152 while (buffer != NULL) { |
4161 SlotsBuffer* next_buffer = buffer->next(); | 4153 SlotsBuffer* next_buffer = buffer->next(); |
4162 DeallocateBuffer(buffer); | 4154 DeallocateBuffer(buffer); |
4163 buffer = next_buffer; | 4155 buffer = next_buffer; |
4164 } | 4156 } |
4165 *buffer_address = NULL; | 4157 *buffer_address = NULL; |
4166 } | 4158 } |
4167 | 4159 |
4168 | 4160 |
4169 } } // namespace v8::internal | 4161 } } // namespace v8::internal |
OLD | NEW |