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

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 1563213002: Type Feedback Vector lives in the closure (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Ports. Created 4 years, 11 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
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/code-stubs.h" 5 #include "src/code-stubs.h"
6 6
7 #include "src/bailout-reason.h" 7 #include "src/bailout-reason.h"
8 #include "src/crankshaft/hydrogen.h" 8 #include "src/crankshaft/hydrogen.h"
9 #include "src/crankshaft/lithium.h" 9 #include "src/crankshaft/lithium.h"
10 #include "src/field-index.h" 10 #include "src/field-index.h"
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 HValue* UnmappedCase(HValue* elements, HValue* key, HValue* value); 86 HValue* UnmappedCase(HValue* elements, HValue* key, HValue* value);
87 HValue* EmitKeyedSloppyArguments(HValue* receiver, HValue* key, 87 HValue* EmitKeyedSloppyArguments(HValue* receiver, HValue* key,
88 HValue* value); 88 HValue* value);
89 89
90 HValue* BuildArrayConstructor(ElementsKind kind, 90 HValue* BuildArrayConstructor(ElementsKind kind,
91 AllocationSiteOverrideMode override_mode, 91 AllocationSiteOverrideMode override_mode,
92 ArgumentClass argument_class); 92 ArgumentClass argument_class);
93 HValue* BuildInternalArrayConstructor(ElementsKind kind, 93 HValue* BuildInternalArrayConstructor(ElementsKind kind,
94 ArgumentClass argument_class); 94 ArgumentClass argument_class);
95 95
96 // BuildCheckAndInstallOptimizedCode emits code to install the optimized
97 // function found in the optimized code map at map_index in js_function, if
98 // the function at map_index matches the given native_context. Builder is
99 // left in the "Then()" state after the install.
100 void BuildCheckAndInstallOptimizedCode(HValue* js_function,
101 HValue* native_context,
102 IfBuilder* builder,
103 HValue* optimized_map,
104 HValue* map_index);
105 void BuildInstallOptimizedCode(HValue* js_function, HValue* native_context,
106 HValue* code_object, HValue* literals);
107 void BuildInstallCode(HValue* js_function, HValue* shared_info);
108
109 HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map,
110 HValue* iterator,
111 int field_offset);
112 void BuildInstallFromOptimizedCodeMap(HValue* js_function,
113 HValue* shared_info,
114 HValue* native_context);
115
116 HValue* BuildToString(HValue* input, bool convert); 96 HValue* BuildToString(HValue* input, bool convert);
117 HValue* BuildToPrimitive(HValue* input, HValue* input_map); 97 HValue* BuildToPrimitive(HValue* input, HValue* input_map);
118 98
119 private: 99 private:
120 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); 100 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
121 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, 101 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
122 ElementsKind kind); 102 ElementsKind kind);
123 103
124 base::SmartArrayPointer<HParameter*> parameters_; 104 base::SmartArrayPointer<HParameter*> parameters_;
125 HValue* arguments_length_; 105 HValue* arguments_length_;
(...skipping 1727 matching lines...) Expand 10 before | Expand all | Expand 10 after
1853 template <> 1833 template <>
1854 HValue* CodeStubGraphBuilder<ToObjectStub>::BuildCodeStub() { 1834 HValue* CodeStubGraphBuilder<ToObjectStub>::BuildCodeStub() {
1855 HValue* receiver = GetParameter(ToObjectDescriptor::kReceiverIndex); 1835 HValue* receiver = GetParameter(ToObjectDescriptor::kReceiverIndex);
1856 return BuildToObject(receiver); 1836 return BuildToObject(receiver);
1857 } 1837 }
1858 1838
1859 1839
1860 Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); } 1840 Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); }
1861 1841
1862 1842
1863 void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode(
1864 HValue* js_function,
1865 HValue* native_context,
1866 IfBuilder* builder,
1867 HValue* optimized_map,
1868 HValue* map_index) {
1869 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt());
1870 HValue* context_slot = LoadFromOptimizedCodeMap(
1871 optimized_map, map_index, SharedFunctionInfo::kContextOffset);
1872 context_slot = Add<HLoadNamedField>(context_slot, nullptr,
1873 HObjectAccess::ForWeakCellValue());
1874 HValue* osr_ast_slot = LoadFromOptimizedCodeMap(
1875 optimized_map, map_index, SharedFunctionInfo::kOsrAstIdOffset);
1876 HValue* code_object = LoadFromOptimizedCodeMap(
1877 optimized_map, map_index, SharedFunctionInfo::kCachedCodeOffset);
1878 code_object = Add<HLoadNamedField>(code_object, nullptr,
1879 HObjectAccess::ForWeakCellValue());
1880 builder->If<HCompareObjectEqAndBranch>(native_context,
1881 context_slot);
1882 builder->AndIf<HCompareObjectEqAndBranch>(osr_ast_slot, osr_ast_id_none);
1883 builder->And();
1884 builder->IfNot<HCompareObjectEqAndBranch>(code_object,
1885 graph()->GetConstant0());
1886 builder->Then();
1887 HValue* literals = LoadFromOptimizedCodeMap(optimized_map,
1888 map_index, SharedFunctionInfo::kLiteralsOffset);
1889 literals = Add<HLoadNamedField>(literals, nullptr,
1890 HObjectAccess::ForWeakCellValue());
1891 IfBuilder maybe_deopt(this);
1892 maybe_deopt.If<HCompareObjectEqAndBranch>(literals, graph()->GetConstant0());
1893 maybe_deopt.ThenDeopt(Deoptimizer::kLiteralsWereDisposed);
1894 maybe_deopt.End();
1895
1896 BuildInstallOptimizedCode(js_function, native_context, code_object, literals);
1897
1898 // The builder continues in the "then" after this function.
1899 }
1900
1901
1902 void CodeStubGraphBuilderBase::BuildInstallOptimizedCode(HValue* js_function,
1903 HValue* native_context,
1904 HValue* code_object,
1905 HValue* literals) {
1906 Counters* counters = isolate()->counters();
1907 AddIncrementCounter(counters->fast_new_closure_install_optimized());
1908
1909 // TODO(fschneider): Idea: store proper code pointers in the optimized code
1910 // map and either unmangle them on marking or do nothing as the whole map is
1911 // discarded on major GC anyway.
1912 Add<HStoreCodeEntry>(js_function, code_object);
1913 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
1914 literals);
1915
1916 // Now link a function into a list of optimized functions.
1917 HValue* optimized_functions_list = Add<HLoadNamedField>(
1918 native_context, nullptr,
1919 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
1920 Add<HStoreNamedField>(js_function,
1921 HObjectAccess::ForNextFunctionLinkPointer(),
1922 optimized_functions_list);
1923
1924 // This store is the only one that should have a write barrier.
1925 Add<HStoreNamedField>(native_context,
1926 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
1927 js_function);
1928 }
1929
1930
1931 void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function,
1932 HValue* shared_info) {
1933 Add<HStoreNamedField>(js_function,
1934 HObjectAccess::ForNextFunctionLinkPointer(),
1935 graph()->GetConstantUndefined());
1936 HValue* code_object = Add<HLoadNamedField>(shared_info, nullptr,
1937 HObjectAccess::ForCodeOffset());
1938 Add<HStoreCodeEntry>(js_function, code_object);
1939 }
1940
1941
1942 HInstruction* CodeStubGraphBuilderBase::LoadFromOptimizedCodeMap(
1943 HValue* optimized_map,
1944 HValue* iterator,
1945 int field_offset) {
1946 // By making sure to express these loads in the form [<hvalue> + constant]
1947 // the keyed load can be hoisted.
1948 DCHECK(field_offset >= 0 && field_offset < SharedFunctionInfo::kEntryLength);
1949 HValue* field_slot = iterator;
1950 if (field_offset > 0) {
1951 HValue* field_offset_value = Add<HConstant>(field_offset);
1952 field_slot = AddUncasted<HAdd>(iterator, field_offset_value);
1953 }
1954 HInstruction* field_entry = Add<HLoadKeyed>(optimized_map, field_slot,
1955 nullptr, nullptr, FAST_ELEMENTS);
1956 return field_entry;
1957 }
1958
1959
1960 void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap(
1961 HValue* js_function,
1962 HValue* shared_info,
1963 HValue* native_context) {
1964 Counters* counters = isolate()->counters();
1965 Factory* factory = isolate()->factory();
1966 IfBuilder is_optimized(this);
1967 HInstruction* optimized_map = Add<HLoadNamedField>(
1968 shared_info, nullptr, HObjectAccess::ForOptimizedCodeMap());
1969 HValue* null_constant = Add<HConstant>(0);
1970 is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant);
1971 is_optimized.Then();
1972 {
1973 BuildInstallCode(js_function, shared_info);
1974 }
1975 is_optimized.Else();
1976 {
1977 AddIncrementCounter(counters->fast_new_closure_try_optimized());
1978 // The {optimized_map} points to fixed array of 4-element entries:
1979 // (native context, optimized code, literals, ast-id).
1980 // Iterate through the {optimized_map} backwards. After the loop, if no
1981 // matching optimized code was found, install unoptimized code.
1982 // for(i = map.length() - SharedFunctionInfo::kEntryLength;
1983 // i >= SharedFunctionInfo::kEntriesStart;
1984 // i -= SharedFunctionInfo::kEntryLength) { ... }
1985 HValue* first_entry_index =
1986 Add<HConstant>(SharedFunctionInfo::kEntriesStart);
1987 HValue* shared_function_entry_length =
1988 Add<HConstant>(SharedFunctionInfo::kEntryLength);
1989 LoopBuilder loop_builder(this, context(), LoopBuilder::kPostDecrement,
1990 shared_function_entry_length);
1991 HValue* array_length = Add<HLoadNamedField>(
1992 optimized_map, nullptr, HObjectAccess::ForFixedArrayLength());
1993 HValue* start_pos =
1994 AddUncasted<HSub>(array_length, shared_function_entry_length);
1995 HValue* slot_iterator =
1996 loop_builder.BeginBody(start_pos, first_entry_index, Token::GTE);
1997 {
1998 IfBuilder done_check(this);
1999 BuildCheckAndInstallOptimizedCode(js_function, native_context,
2000 &done_check, optimized_map,
2001 slot_iterator);
2002 // Fall out of the loop
2003 loop_builder.Break();
2004 }
2005 loop_builder.EndBody();
2006
2007 // If {slot_iterator} is less than the first entry index, then we failed to
2008 // find a context-dependent code and try context-independent code next.
2009 IfBuilder no_optimized_code_check(this);
2010 no_optimized_code_check.If<HCompareNumericAndBranch>(
2011 slot_iterator, first_entry_index, Token::LT);
2012 no_optimized_code_check.Then();
2013 {
2014 IfBuilder shared_code_check(this);
2015 HValue* shared_code =
2016 Add<HLoadNamedField>(optimized_map, nullptr,
2017 HObjectAccess::ForOptimizedCodeMapSharedCode());
2018 shared_code = Add<HLoadNamedField>(shared_code, nullptr,
2019 HObjectAccess::ForWeakCellValue());
2020 shared_code_check.IfNot<HCompareObjectEqAndBranch>(
2021 shared_code, graph()->GetConstant0());
2022 shared_code_check.Then();
2023 {
2024 // Store the context-independent optimized code.
2025 HValue* literals = Add<HConstant>(factory->empty_fixed_array());
2026 BuildInstallOptimizedCode(js_function, native_context, shared_code,
2027 literals);
2028 }
2029 shared_code_check.Else();
2030 {
2031 // Store the unoptimized code.
2032 BuildInstallCode(js_function, shared_info);
2033 }
2034 }
2035 }
2036 }
2037
2038
2039 template<> 1843 template<>
2040 HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() { 1844 HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
2041 Counters* counters = isolate()->counters(); 1845 Counters* counters = isolate()->counters();
2042 Factory* factory = isolate()->factory(); 1846 Factory* factory = isolate()->factory();
2043 HInstruction* empty_fixed_array = 1847 HInstruction* empty_fixed_array =
2044 Add<HConstant>(factory->empty_fixed_array()); 1848 Add<HConstant>(factory->empty_fixed_array());
1849 HInstruction* empty_literals_array =
1850 Add<HConstant>(factory->empty_literals_array());
2045 HValue* shared_info = GetParameter(0); 1851 HValue* shared_info = GetParameter(0);
2046 1852
2047 AddIncrementCounter(counters->fast_new_closure_total()); 1853 AddIncrementCounter(counters->fast_new_closure_total());
2048 1854
2049 // Create a new closure from the given function info in new space 1855 // Create a new closure from the given function info in new space
2050 HValue* size = Add<HConstant>(JSFunction::kSize); 1856 HValue* size = Add<HConstant>(JSFunction::kSize);
2051 HInstruction* js_function = 1857 HInstruction* js_function =
2052 Add<HAllocate>(size, HType::JSObject(), NOT_TENURED, JS_FUNCTION_TYPE); 1858 Add<HAllocate>(size, HType::JSObject(), NOT_TENURED, JS_FUNCTION_TYPE);
2053 1859
2054 int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(), 1860 int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(),
2055 casted_stub()->kind()); 1861 casted_stub()->kind());
2056 1862
2057 // Compute the function map in the current native context and set that 1863 // Compute the function map in the current native context and set that
2058 // as the map of the allocated object. 1864 // as the map of the allocated object.
2059 HInstruction* native_context = BuildGetNativeContext(); 1865 HInstruction* native_context = BuildGetNativeContext();
2060 HInstruction* map_slot_value = Add<HLoadNamedField>( 1866 HInstruction* map_slot_value = Add<HLoadNamedField>(
2061 native_context, nullptr, HObjectAccess::ForContextSlot(map_index)); 1867 native_context, nullptr, HObjectAccess::ForContextSlot(map_index));
2062 Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value); 1868 Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value);
2063 1869
2064 // Initialize the rest of the function. 1870 // Initialize the rest of the function.
2065 Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(), 1871 Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(),
2066 empty_fixed_array); 1872 empty_fixed_array);
2067 Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(), 1873 Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(),
2068 empty_fixed_array); 1874 empty_fixed_array);
2069 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(), 1875 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
2070 empty_fixed_array); 1876 empty_literals_array);
2071 Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(), 1877 Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
2072 graph()->GetConstantHole()); 1878 graph()->GetConstantHole());
2073 Add<HStoreNamedField>( 1879 Add<HStoreNamedField>(
2074 js_function, HObjectAccess::ForSharedFunctionInfoPointer(), shared_info); 1880 js_function, HObjectAccess::ForSharedFunctionInfoPointer(), shared_info);
2075 Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(), 1881 Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
2076 context()); 1882 context());
2077 1883 Handle<Code> lazy_builtin(
2078 // Initialize the code pointer in the function to be the one found in the 1884 isolate()->builtins()->builtin(Builtins::kCompileLazy));
2079 // shared function info object. But first check if there is an optimized 1885 HConstant* lazy = Add<HConstant>(lazy_builtin);
2080 // version for our context. 1886 Add<HStoreCodeEntry>(js_function, lazy);
2081 BuildInstallFromOptimizedCodeMap(js_function, shared_info, native_context); 1887 Add<HStoreNamedField>(js_function,
2082 1888 HObjectAccess::ForNextFunctionLinkPointer(),
1889 graph()->GetConstantUndefined());
2083 return js_function; 1890 return js_function;
2084 } 1891 }
2085 1892
2086 1893
2087 Handle<Code> FastNewClosureStub::GenerateCode() { 1894 Handle<Code> FastNewClosureStub::GenerateCode() {
2088 return DoGenerateCode(this); 1895 return DoGenerateCode(this);
2089 } 1896 }
2090 1897
2091 1898
2092 template<> 1899 template<>
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
2426 return Pop(); 2233 return Pop();
2427 } 2234 }
2428 2235
2429 2236
2430 Handle<Code> KeyedLoadGenericStub::GenerateCode() { 2237 Handle<Code> KeyedLoadGenericStub::GenerateCode() {
2431 return DoGenerateCode(this); 2238 return DoGenerateCode(this);
2432 } 2239 }
2433 2240
2434 } // namespace internal 2241 } // namespace internal
2435 } // namespace v8 2242 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/compiler.h » ('j') | src/crankshaft/hydrogen.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698