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

Side by Side Diff: src/heap.cc

Issue 188783003: Make maps in monomorphic IC stubs weak. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase, address comments Created 6 years, 8 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
« no previous file with comments | « src/handles.cc ('k') | src/ic.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 // 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 1692 matching lines...) Expand 10 before | Expand all | Expand 10 after
1703 if (external_string_table_.old_space_strings_.length() > 0) { 1703 if (external_string_table_.old_space_strings_.length() > 0) {
1704 Object** start = &external_string_table_.old_space_strings_[0]; 1704 Object** start = &external_string_table_.old_space_strings_[0];
1705 Object** end = start + external_string_table_.old_space_strings_.length(); 1705 Object** end = start + external_string_table_.old_space_strings_.length();
1706 for (Object** p = start; p < end; ++p) *p = updater_func(this, p); 1706 for (Object** p = start; p < end; ++p) *p = updater_func(this, p);
1707 } 1707 }
1708 1708
1709 UpdateNewSpaceReferencesInExternalStringTable(updater_func); 1709 UpdateNewSpaceReferencesInExternalStringTable(updater_func);
1710 } 1710 }
1711 1711
1712 1712
1713 template <class T>
1714 struct WeakListVisitor;
1715
1716
1717 template <class T>
1718 static Object* VisitWeakList(Heap* heap,
1719 Object* list,
1720 WeakObjectRetainer* retainer,
1721 bool record_slots) {
1722 Object* undefined = heap->undefined_value();
1723 Object* head = undefined;
1724 T* tail = NULL;
1725 MarkCompactCollector* collector = heap->mark_compact_collector();
1726 while (list != undefined) {
1727 // Check whether to keep the candidate in the list.
1728 T* candidate = reinterpret_cast<T*>(list);
1729 Object* retained = retainer->RetainAs(list);
1730 if (retained != NULL) {
1731 if (head == undefined) {
1732 // First element in the list.
1733 head = retained;
1734 } else {
1735 // Subsequent elements in the list.
1736 ASSERT(tail != NULL);
1737 WeakListVisitor<T>::SetWeakNext(tail, retained);
1738 if (record_slots) {
1739 Object** next_slot =
1740 HeapObject::RawField(tail, WeakListVisitor<T>::WeakNextOffset());
1741 collector->RecordSlot(next_slot, next_slot, retained);
1742 }
1743 }
1744 // Retained object is new tail.
1745 ASSERT(!retained->IsUndefined());
1746 candidate = reinterpret_cast<T*>(retained);
1747 tail = candidate;
1748
1749
1750 // tail is a live object, visit it.
1751 WeakListVisitor<T>::VisitLiveObject(
1752 heap, tail, retainer, record_slots);
1753 } else {
1754 WeakListVisitor<T>::VisitPhantomObject(heap, candidate);
1755 }
1756
1757 // Move to next element in the list.
1758 list = WeakListVisitor<T>::WeakNext(candidate);
1759 }
1760
1761 // Terminate the list if there is one or more elements.
1762 if (tail != NULL) {
1763 WeakListVisitor<T>::SetWeakNext(tail, undefined);
1764 }
1765 return head;
1766 }
1767
1768
1769 template <class T>
1770 static void ClearWeakList(Heap* heap,
1771 Object* list) {
1772 Object* undefined = heap->undefined_value();
1773 while (list != undefined) {
1774 T* candidate = reinterpret_cast<T*>(list);
1775 list = WeakListVisitor<T>::WeakNext(candidate);
1776 WeakListVisitor<T>::SetWeakNext(candidate, undefined);
1777 }
1778 }
1779
1780
1781 template<>
1782 struct WeakListVisitor<JSFunction> {
1783 static void SetWeakNext(JSFunction* function, Object* next) {
1784 function->set_next_function_link(next);
1785 }
1786
1787 static Object* WeakNext(JSFunction* function) {
1788 return function->next_function_link();
1789 }
1790
1791 static int WeakNextOffset() {
1792 return JSFunction::kNextFunctionLinkOffset;
1793 }
1794
1795 static void VisitLiveObject(Heap*, JSFunction*,
1796 WeakObjectRetainer*, bool) {
1797 }
1798
1799 static void VisitPhantomObject(Heap*, JSFunction*) {
1800 }
1801 };
1802
1803
1804 template<>
1805 struct WeakListVisitor<Code> {
1806 static void SetWeakNext(Code* code, Object* next) {
1807 code->set_next_code_link(next);
1808 }
1809
1810 static Object* WeakNext(Code* code) {
1811 return code->next_code_link();
1812 }
1813
1814 static int WeakNextOffset() {
1815 return Code::kNextCodeLinkOffset;
1816 }
1817
1818 static void VisitLiveObject(Heap*, Code*,
1819 WeakObjectRetainer*, bool) {
1820 }
1821
1822 static void VisitPhantomObject(Heap*, Code*) {
1823 }
1824 };
1825
1826
1827 template<>
1828 struct WeakListVisitor<Context> {
1829 static void SetWeakNext(Context* context, Object* next) {
1830 context->set(Context::NEXT_CONTEXT_LINK,
1831 next,
1832 UPDATE_WRITE_BARRIER);
1833 }
1834
1835 static Object* WeakNext(Context* context) {
1836 return context->get(Context::NEXT_CONTEXT_LINK);
1837 }
1838
1839 static void VisitLiveObject(Heap* heap,
1840 Context* context,
1841 WeakObjectRetainer* retainer,
1842 bool record_slots) {
1843 // Process the three weak lists linked off the context.
1844 DoWeakList<JSFunction>(heap, context, retainer, record_slots,
1845 Context::OPTIMIZED_FUNCTIONS_LIST);
1846 DoWeakList<Code>(heap, context, retainer, record_slots,
1847 Context::OPTIMIZED_CODE_LIST);
1848 DoWeakList<Code>(heap, context, retainer, record_slots,
1849 Context::DEOPTIMIZED_CODE_LIST);
1850 }
1851
1852 template<class T>
1853 static void DoWeakList(Heap* heap,
1854 Context* context,
1855 WeakObjectRetainer* retainer,
1856 bool record_slots,
1857 int index) {
1858 // Visit the weak list, removing dead intermediate elements.
1859 Object* list_head = VisitWeakList<T>(heap, context->get(index), retainer,
1860 record_slots);
1861
1862 // Update the list head.
1863 context->set(index, list_head, UPDATE_WRITE_BARRIER);
1864
1865 if (record_slots) {
1866 // Record the updated slot if necessary.
1867 Object** head_slot = HeapObject::RawField(
1868 context, FixedArray::SizeFor(index));
1869 heap->mark_compact_collector()->RecordSlot(
1870 head_slot, head_slot, list_head);
1871 }
1872 }
1873
1874 static void VisitPhantomObject(Heap* heap, Context* context) {
1875 ClearWeakList<JSFunction>(heap,
1876 context->get(Context::OPTIMIZED_FUNCTIONS_LIST));
1877 ClearWeakList<Code>(heap, context->get(Context::OPTIMIZED_CODE_LIST));
1878 ClearWeakList<Code>(heap, context->get(Context::DEOPTIMIZED_CODE_LIST));
1879 }
1880
1881 static int WeakNextOffset() {
1882 return FixedArray::SizeFor(Context::NEXT_CONTEXT_LINK);
1883 }
1884 };
1885
1886
1887 void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { 1713 void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
1888 // We don't record weak slots during marking or scavenges. 1714 // We don't record weak slots during marking or scavenges.
1889 // Instead we do it once when we complete mark-compact cycle. 1715 // Instead we do it once when we complete mark-compact cycle.
1890 // Note that write barrier has no effect if we are already in the middle of 1716 // Note that write barrier has no effect if we are already in the middle of
1891 // compacting mark-sweep cycle and we have to record slots manually. 1717 // compacting mark-sweep cycle and we have to record slots manually.
1892 bool record_slots = 1718 bool record_slots =
1893 gc_state() == MARK_COMPACT && 1719 gc_state() == MARK_COMPACT &&
1894 mark_compact_collector()->is_compacting(); 1720 mark_compact_collector()->is_compacting();
1895 ProcessArrayBuffers(retainer, record_slots); 1721 ProcessArrayBuffers(retainer, record_slots);
1896 ProcessNativeContexts(retainer, record_slots); 1722 ProcessNativeContexts(retainer, record_slots);
1897 // TODO(mvstanton): AllocationSites only need to be processed during 1723 // TODO(mvstanton): AllocationSites only need to be processed during
1898 // MARK_COMPACT, as they live in old space. Verify and address. 1724 // MARK_COMPACT, as they live in old space. Verify and address.
1899 ProcessAllocationSites(retainer, record_slots); 1725 ProcessAllocationSites(retainer, record_slots);
1900 } 1726 }
1901 1727
1902 void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer, 1728 void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer,
1903 bool record_slots) { 1729 bool record_slots) {
1904 Object* head = 1730 Object* head =
1905 VisitWeakList<Context>( 1731 VisitWeakList<Context>(
1906 this, native_contexts_list(), retainer, record_slots); 1732 this, native_contexts_list(), retainer, record_slots);
1907 // Update the head of the list of contexts. 1733 // Update the head of the list of contexts.
1908 native_contexts_list_ = head; 1734 native_contexts_list_ = head;
1909 } 1735 }
1910 1736
1911 1737
1912 template<>
1913 struct WeakListVisitor<JSArrayBufferView> {
1914 static void SetWeakNext(JSArrayBufferView* obj, Object* next) {
1915 obj->set_weak_next(next);
1916 }
1917
1918 static Object* WeakNext(JSArrayBufferView* obj) {
1919 return obj->weak_next();
1920 }
1921
1922 static void VisitLiveObject(Heap*,
1923 JSArrayBufferView* obj,
1924 WeakObjectRetainer* retainer,
1925 bool record_slots) {}
1926
1927 static void VisitPhantomObject(Heap*, JSArrayBufferView*) {}
1928
1929 static int WeakNextOffset() {
1930 return JSArrayBufferView::kWeakNextOffset;
1931 }
1932 };
1933
1934
1935 template<>
1936 struct WeakListVisitor<JSArrayBuffer> {
1937 static void SetWeakNext(JSArrayBuffer* obj, Object* next) {
1938 obj->set_weak_next(next);
1939 }
1940
1941 static Object* WeakNext(JSArrayBuffer* obj) {
1942 return obj->weak_next();
1943 }
1944
1945 static void VisitLiveObject(Heap* heap,
1946 JSArrayBuffer* array_buffer,
1947 WeakObjectRetainer* retainer,
1948 bool record_slots) {
1949 Object* typed_array_obj =
1950 VisitWeakList<JSArrayBufferView>(
1951 heap,
1952 array_buffer->weak_first_view(),
1953 retainer, record_slots);
1954 array_buffer->set_weak_first_view(typed_array_obj);
1955 if (typed_array_obj != heap->undefined_value() && record_slots) {
1956 Object** slot = HeapObject::RawField(
1957 array_buffer, JSArrayBuffer::kWeakFirstViewOffset);
1958 heap->mark_compact_collector()->RecordSlot(slot, slot, typed_array_obj);
1959 }
1960 }
1961
1962 static void VisitPhantomObject(Heap* heap, JSArrayBuffer* phantom) {
1963 Runtime::FreeArrayBuffer(heap->isolate(), phantom);
1964 }
1965
1966 static int WeakNextOffset() {
1967 return JSArrayBuffer::kWeakNextOffset;
1968 }
1969 };
1970
1971
1972 void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer, 1738 void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer,
1973 bool record_slots) { 1739 bool record_slots) {
1974 Object* array_buffer_obj = 1740 Object* array_buffer_obj =
1975 VisitWeakList<JSArrayBuffer>(this, 1741 VisitWeakList<JSArrayBuffer>(this,
1976 array_buffers_list(), 1742 array_buffers_list(),
1977 retainer, record_slots); 1743 retainer, record_slots);
1978 set_array_buffers_list(array_buffer_obj); 1744 set_array_buffers_list(array_buffer_obj);
1979 } 1745 }
1980 1746
1981 1747
1982 void Heap::TearDownArrayBuffers() { 1748 void Heap::TearDownArrayBuffers() {
1983 Object* undefined = undefined_value(); 1749 Object* undefined = undefined_value();
1984 for (Object* o = array_buffers_list(); o != undefined;) { 1750 for (Object* o = array_buffers_list(); o != undefined;) {
1985 JSArrayBuffer* buffer = JSArrayBuffer::cast(o); 1751 JSArrayBuffer* buffer = JSArrayBuffer::cast(o);
1986 Runtime::FreeArrayBuffer(isolate(), buffer); 1752 Runtime::FreeArrayBuffer(isolate(), buffer);
1987 o = buffer->weak_next(); 1753 o = buffer->weak_next();
1988 } 1754 }
1989 array_buffers_list_ = undefined; 1755 array_buffers_list_ = undefined;
1990 } 1756 }
1991 1757
1992 1758
1993 template<>
1994 struct WeakListVisitor<AllocationSite> {
1995 static void SetWeakNext(AllocationSite* obj, Object* next) {
1996 obj->set_weak_next(next);
1997 }
1998
1999 static Object* WeakNext(AllocationSite* obj) {
2000 return obj->weak_next();
2001 }
2002
2003 static void VisitLiveObject(Heap* heap,
2004 AllocationSite* site,
2005 WeakObjectRetainer* retainer,
2006 bool record_slots) {}
2007
2008 static void VisitPhantomObject(Heap* heap, AllocationSite* phantom) {}
2009
2010 static int WeakNextOffset() {
2011 return AllocationSite::kWeakNextOffset;
2012 }
2013 };
2014
2015
2016 void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer, 1759 void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer,
2017 bool record_slots) { 1760 bool record_slots) {
2018 Object* allocation_site_obj = 1761 Object* allocation_site_obj =
2019 VisitWeakList<AllocationSite>(this, 1762 VisitWeakList<AllocationSite>(this,
2020 allocation_sites_list(), 1763 allocation_sites_list(),
2021 retainer, record_slots); 1764 retainer, record_slots);
2022 set_allocation_sites_list(allocation_site_obj); 1765 set_allocation_sites_list(allocation_site_obj);
2023 } 1766 }
2024 1767
2025 1768
(...skipping 2130 matching lines...) Expand 10 before | Expand all | Expand 10 after
4156 code->set_raw_kind_specific_flags2(0); 3899 code->set_raw_kind_specific_flags2(0);
4157 code->set_is_crankshafted(crankshafted); 3900 code->set_is_crankshafted(crankshafted);
4158 code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER); 3901 code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER);
4159 code->set_raw_type_feedback_info(undefined_value()); 3902 code->set_raw_type_feedback_info(undefined_value());
4160 code->set_next_code_link(undefined_value()); 3903 code->set_next_code_link(undefined_value());
4161 code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER); 3904 code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER);
4162 code->set_gc_metadata(Smi::FromInt(0)); 3905 code->set_gc_metadata(Smi::FromInt(0));
4163 code->set_ic_age(global_ic_age_); 3906 code->set_ic_age(global_ic_age_);
4164 code->set_prologue_offset(prologue_offset); 3907 code->set_prologue_offset(prologue_offset);
4165 if (code->kind() == Code::OPTIMIZED_FUNCTION) { 3908 if (code->kind() == Code::OPTIMIZED_FUNCTION) {
4166 code->set_marked_for_deoptimization(false); 3909 ASSERT(!code->marked_for_deoptimization());
3910 }
3911 if (code->is_inline_cache_stub()) {
3912 ASSERT(!code->is_weak_stub());
3913 ASSERT(!code->is_invalidated_weak_stub());
4167 } 3914 }
4168 3915
4169 if (FLAG_enable_ool_constant_pool) { 3916 if (FLAG_enable_ool_constant_pool) {
4170 desc.origin->PopulateConstantPool(constant_pool); 3917 desc.origin->PopulateConstantPool(constant_pool);
4171 } 3918 }
4172 code->set_constant_pool(constant_pool); 3919 code->set_constant_pool(constant_pool);
4173 3920
4174 #ifdef ENABLE_DEBUGGER_SUPPORT 3921 #ifdef ENABLE_DEBUGGER_SUPPORT
4175 if (code->kind() == Code::FUNCTION) { 3922 if (code->kind() == Code::FUNCTION) {
4176 code->set_has_debug_break_slots( 3923 code->set_has_debug_break_slots(
(...skipping 3432 matching lines...) Expand 10 before | Expand all | Expand 10 after
7609 static_cast<int>(object_sizes_last_time_[index])); 7356 static_cast<int>(object_sizes_last_time_[index]));
7610 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 7357 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
7611 #undef ADJUST_LAST_TIME_OBJECT_COUNT 7358 #undef ADJUST_LAST_TIME_OBJECT_COUNT
7612 7359
7613 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 7360 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
7614 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 7361 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
7615 ClearObjectStats(); 7362 ClearObjectStats();
7616 } 7363 }
7617 7364
7618 } } // namespace v8::internal 7365 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/handles.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698