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

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

Issue 2605893002: [builtins] More stubs to the builtin-o-sphere. (Closed)
Patch Set: Fixed compile error. Created 3 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
« no previous file with comments | « src/code-stubs.h ('k') | src/compiler/js-generic-lowering.cc » ('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/code-stubs.h" 5 #include "src/code-stubs.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/ast/ast.h" 9 #include "src/ast/ast.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 1759 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 &if_keyisinvalid); 1770 &if_keyisinvalid);
1771 assembler.Bind(&if_keyispositivesmi); 1771 assembler.Bind(&if_keyispositivesmi);
1772 assembler.TailCallRuntime(Runtime::kLoadElementWithInterceptor, context, 1772 assembler.TailCallRuntime(Runtime::kLoadElementWithInterceptor, context,
1773 receiver, key); 1773 receiver, key);
1774 1774
1775 assembler.Bind(&if_keyisinvalid); 1775 assembler.Bind(&if_keyisinvalid);
1776 assembler.TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, 1776 assembler.TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key,
1777 slot, vector); 1777 slot, vector);
1778 } 1778 }
1779 1779
1780 // static
1781 int FastCloneShallowObjectStub::PropertiesCount(int literal_length) {
1782 // This heuristic of setting empty literals to have
1783 // kInitialGlobalObjectUnusedPropertiesCount must remain in-sync with the
1784 // runtime.
1785 // TODO(verwaest): Unify this with the heuristic in the runtime.
1786 return literal_length == 0
1787 ? JSObject::kInitialGlobalObjectUnusedPropertiesCount
1788 : literal_length;
1789 }
1790
1791 // static
1792 compiler::Node* FastCloneShallowObjectStub::GenerateFastPath(
1793 CodeStubAssembler* assembler, compiler::CodeAssembler::Label* call_runtime,
1794 compiler::Node* closure, compiler::Node* literals_index,
1795 compiler::Node* properties_count) {
1796 typedef compiler::Node Node;
1797 typedef compiler::CodeAssembler::Label Label;
1798 typedef compiler::CodeAssembler::Variable Variable;
1799
1800 Node* literals_array =
1801 assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset);
1802 Node* allocation_site = assembler->LoadFixedArrayElement(
1803 literals_array, literals_index,
1804 LiteralsArray::kFirstLiteralIndex * kPointerSize,
1805 CodeStubAssembler::SMI_PARAMETERS);
1806 assembler->GotoIf(assembler->IsUndefined(allocation_site), call_runtime);
1807
1808 // Calculate the object and allocation size based on the properties count.
1809 Node* object_size = assembler->IntPtrAdd(
1810 assembler->WordShl(properties_count, kPointerSizeLog2),
1811 assembler->IntPtrConstant(JSObject::kHeaderSize));
1812 Node* allocation_size = object_size;
1813 if (FLAG_allocation_site_pretenuring) {
1814 allocation_size = assembler->IntPtrAdd(
1815 object_size, assembler->IntPtrConstant(AllocationMemento::kSize));
1816 }
1817 Node* boilerplate = assembler->LoadObjectField(
1818 allocation_site, AllocationSite::kTransitionInfoOffset);
1819 Node* boilerplate_map = assembler->LoadMap(boilerplate);
1820 Node* instance_size = assembler->LoadMapInstanceSize(boilerplate_map);
1821 Node* size_in_words = assembler->WordShr(object_size, kPointerSizeLog2);
1822 assembler->GotoUnless(assembler->WordEqual(instance_size, size_in_words),
1823 call_runtime);
1824
1825 Node* copy = assembler->Allocate(allocation_size);
1826
1827 // Copy boilerplate elements.
1828 Variable offset(assembler, MachineType::PointerRepresentation());
1829 offset.Bind(assembler->IntPtrConstant(-kHeapObjectTag));
1830 Node* end_offset = assembler->IntPtrAdd(object_size, offset.value());
1831 Label loop_body(assembler, &offset), loop_check(assembler, &offset);
1832 // We should always have an object size greater than zero.
1833 assembler->Goto(&loop_body);
1834 assembler->Bind(&loop_body);
1835 {
1836 // The Allocate above guarantees that the copy lies in new space. This
1837 // allows us to skip write barriers. This is necessary since we may also be
1838 // copying unboxed doubles.
1839 Node* field =
1840 assembler->Load(MachineType::IntPtr(), boilerplate, offset.value());
1841 assembler->StoreNoWriteBarrier(MachineType::PointerRepresentation(), copy,
1842 offset.value(), field);
1843 assembler->Goto(&loop_check);
1844 }
1845 assembler->Bind(&loop_check);
1846 {
1847 offset.Bind(assembler->IntPtrAdd(offset.value(),
1848 assembler->IntPtrConstant(kPointerSize)));
1849 assembler->GotoUnless(
1850 assembler->IntPtrGreaterThanOrEqual(offset.value(), end_offset),
1851 &loop_body);
1852 }
1853
1854 if (FLAG_allocation_site_pretenuring) {
1855 Node* memento = assembler->InnerAllocate(copy, object_size);
1856 assembler->StoreMapNoWriteBarrier(memento,
1857 Heap::kAllocationMementoMapRootIndex);
1858 assembler->StoreObjectFieldNoWriteBarrier(
1859 memento, AllocationMemento::kAllocationSiteOffset, allocation_site);
1860 Node* memento_create_count = assembler->LoadObjectField(
1861 allocation_site, AllocationSite::kPretenureCreateCountOffset);
1862 memento_create_count = assembler->SmiAdd(
1863 memento_create_count, assembler->SmiConstant(Smi::FromInt(1)));
1864 assembler->StoreObjectFieldNoWriteBarrier(
1865 allocation_site, AllocationSite::kPretenureCreateCountOffset,
1866 memento_create_count);
1867 }
1868
1869 // TODO(verwaest): Allocate and fill in double boxes.
1870 return copy;
1871 }
1872
1873 void FastCloneShallowObjectStub::GenerateAssembly(
1874 compiler::CodeAssemblerState* state) const {
1875 typedef CodeStubAssembler::Label Label;
1876 typedef compiler::Node Node;
1877 CodeStubAssembler assembler(state);
1878
1879 Label call_runtime(&assembler);
1880 Node* closure = assembler.Parameter(0);
1881 Node* literals_index = assembler.Parameter(1);
1882
1883 Node* properties_count =
1884 assembler.IntPtrConstant(PropertiesCount(this->length()));
1885 Node* copy = GenerateFastPath(&assembler, &call_runtime, closure,
1886 literals_index, properties_count);
1887 assembler.Return(copy);
1888
1889 assembler.Bind(&call_runtime);
1890 Node* constant_properties = assembler.Parameter(2);
1891 Node* flags = assembler.Parameter(3);
1892 Node* context = assembler.Parameter(4);
1893 assembler.TailCallRuntime(Runtime::kCreateObjectLiteral, context, closure,
1894 literals_index, constant_properties, flags);
1895 }
1896
1897 template<class StateType> 1780 template<class StateType>
1898 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { 1781 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) {
1899 // Note: Although a no-op transition is semantically OK, it is hinting at a 1782 // Note: Although a no-op transition is semantically OK, it is hinting at a
1900 // bug somewhere in our state transition machinery. 1783 // bug somewhere in our state transition machinery.
1901 DCHECK(from != to); 1784 DCHECK(from != to);
1902 if (V8_LIKELY(!FLAG_ic_stats)) return; 1785 if (V8_LIKELY(!FLAG_ic_stats)) return;
1903 if (FLAG_ic_stats & 1786 if (FLAG_ic_stats &
1904 v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) { 1787 v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
1905 auto ic_stats = ICStats::instance(); 1788 auto ic_stats = ICStats::instance();
1906 ic_stats->Begin(); 1789 ic_stats->Begin();
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
2046 { 1929 {
2047 var_result.Bind( 1930 var_result.Bind(
2048 assembler.CallRuntime(Runtime::kGetProperty, context, object, key)); 1931 assembler.CallRuntime(Runtime::kGetProperty, context, object, key));
2049 assembler.Goto(&end); 1932 assembler.Goto(&end);
2050 } 1933 }
2051 1934
2052 assembler.Bind(&end); 1935 assembler.Bind(&end);
2053 assembler.Return(var_result.value()); 1936 assembler.Return(var_result.value());
2054 } 1937 }
2055 1938
2056 // static
2057 compiler::Node* FastCloneRegExpStub::Generate(CodeStubAssembler* assembler,
2058 compiler::Node* closure,
2059 compiler::Node* literal_index,
2060 compiler::Node* pattern,
2061 compiler::Node* flags,
2062 compiler::Node* context) {
2063 typedef CodeStubAssembler::Label Label;
2064 typedef CodeStubAssembler::Variable Variable;
2065 typedef compiler::Node Node;
2066
2067 Label call_runtime(assembler, Label::kDeferred), end(assembler);
2068
2069 Variable result(assembler, MachineRepresentation::kTagged);
2070
2071 Node* literals_array =
2072 assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset);
2073 Node* boilerplate = assembler->LoadFixedArrayElement(
2074 literals_array, literal_index,
2075 LiteralsArray::kFirstLiteralIndex * kPointerSize,
2076 CodeStubAssembler::SMI_PARAMETERS);
2077 assembler->GotoIf(assembler->IsUndefined(boilerplate), &call_runtime);
2078
2079 {
2080 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
2081 Node* copy = assembler->Allocate(size);
2082 for (int offset = 0; offset < size; offset += kPointerSize) {
2083 Node* value = assembler->LoadObjectField(boilerplate, offset);
2084 assembler->StoreObjectFieldNoWriteBarrier(copy, offset, value);
2085 }
2086 result.Bind(copy);
2087 assembler->Goto(&end);
2088 }
2089
2090 assembler->Bind(&call_runtime);
2091 {
2092 result.Bind(assembler->CallRuntime(Runtime::kCreateRegExpLiteral, context,
2093 closure, literal_index, pattern, flags));
2094 assembler->Goto(&end);
2095 }
2096
2097 assembler->Bind(&end);
2098 return result.value();
2099 }
2100
2101 void FastCloneRegExpStub::GenerateAssembly(
2102 compiler::CodeAssemblerState* state) const {
2103 typedef compiler::Node Node;
2104 CodeStubAssembler assembler(state);
2105 Node* closure = assembler.Parameter(Descriptor::kClosure);
2106 Node* literal_index = assembler.Parameter(Descriptor::kLiteralIndex);
2107 Node* pattern = assembler.Parameter(Descriptor::kPattern);
2108 Node* flags = assembler.Parameter(Descriptor::kFlags);
2109 Node* context = assembler.Parameter(Descriptor::kContext);
2110
2111 assembler.Return(
2112 Generate(&assembler, closure, literal_index, pattern, flags, context));
2113 }
2114
2115 namespace {
2116
2117 compiler::Node* NonEmptyShallowClone(CodeStubAssembler* assembler,
2118 compiler::Node* boilerplate,
2119 compiler::Node* boilerplate_map,
2120 compiler::Node* boilerplate_elements,
2121 compiler::Node* allocation_site,
2122 compiler::Node* capacity,
2123 ElementsKind kind) {
2124 typedef compiler::Node Node;
2125 typedef CodeStubAssembler::ParameterMode ParameterMode;
2126
2127 ParameterMode param_mode = assembler->OptimalParameterMode();
2128
2129 Node* length = assembler->LoadJSArrayLength(boilerplate);
2130 capacity = assembler->TaggedToParameter(capacity, param_mode);
2131
2132 Node *array, *elements;
2133 std::tie(array, elements) =
2134 assembler->AllocateUninitializedJSArrayWithElements(
2135 kind, boilerplate_map, length, allocation_site, capacity, param_mode);
2136
2137 assembler->Comment("copy elements header");
2138 // Header consists of map and length.
2139 STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize);
2140 assembler->StoreMap(elements, assembler->LoadMap(boilerplate_elements));
2141 {
2142 int offset = FixedArrayBase::kLengthOffset;
2143 assembler->StoreObjectFieldNoWriteBarrier(
2144 elements, offset,
2145 assembler->LoadObjectField(boilerplate_elements, offset));
2146 }
2147
2148 length = assembler->TaggedToParameter(length, param_mode);
2149
2150 assembler->Comment("copy boilerplate elements");
2151 assembler->CopyFixedArrayElements(kind, boilerplate_elements, elements,
2152 length, SKIP_WRITE_BARRIER, param_mode);
2153 assembler->IncrementCounter(
2154 assembler->isolate()->counters()->inlined_copied_elements(), 1);
2155
2156 return array;
2157 }
2158
2159 } // namespace
2160
2161 // static
2162 compiler::Node* FastCloneShallowArrayStub::Generate(
2163 CodeStubAssembler* assembler, compiler::Node* closure,
2164 compiler::Node* literal_index, compiler::Node* context,
2165 CodeStubAssembler::Label* call_runtime,
2166 AllocationSiteMode allocation_site_mode) {
2167 typedef CodeStubAssembler::Label Label;
2168 typedef CodeStubAssembler::Variable Variable;
2169 typedef compiler::Node Node;
2170
2171 Label zero_capacity(assembler), cow_elements(assembler),
2172 fast_elements(assembler), return_result(assembler);
2173 Variable result(assembler, MachineRepresentation::kTagged);
2174
2175 Node* literals_array =
2176 assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset);
2177 Node* allocation_site = assembler->LoadFixedArrayElement(
2178 literals_array, literal_index,
2179 LiteralsArray::kFirstLiteralIndex * kPointerSize,
2180 CodeStubAssembler::SMI_PARAMETERS);
2181
2182 assembler->GotoIf(assembler->IsUndefined(allocation_site), call_runtime);
2183 allocation_site = assembler->LoadFixedArrayElement(
2184 literals_array, literal_index,
2185 LiteralsArray::kFirstLiteralIndex * kPointerSize,
2186 CodeStubAssembler::SMI_PARAMETERS);
2187
2188 Node* boilerplate = assembler->LoadObjectField(
2189 allocation_site, AllocationSite::kTransitionInfoOffset);
2190 Node* boilerplate_map = assembler->LoadMap(boilerplate);
2191 Node* boilerplate_elements = assembler->LoadElements(boilerplate);
2192 Node* capacity = assembler->LoadFixedArrayBaseLength(boilerplate_elements);
2193 allocation_site =
2194 allocation_site_mode == TRACK_ALLOCATION_SITE ? allocation_site : nullptr;
2195
2196 Node* zero = assembler->SmiConstant(Smi::kZero);
2197 assembler->GotoIf(assembler->SmiEqual(capacity, zero), &zero_capacity);
2198
2199 Node* elements_map = assembler->LoadMap(boilerplate_elements);
2200 assembler->GotoIf(assembler->IsFixedCOWArrayMap(elements_map), &cow_elements);
2201
2202 assembler->GotoIf(assembler->IsFixedArrayMap(elements_map), &fast_elements);
2203 {
2204 assembler->Comment("fast double elements path");
2205 if (FLAG_debug_code) {
2206 Label correct_elements_map(assembler), abort(assembler, Label::kDeferred);
2207 assembler->Branch(assembler->IsFixedDoubleArrayMap(elements_map),
2208 &correct_elements_map, &abort);
2209
2210 assembler->Bind(&abort);
2211 {
2212 Node* abort_id = assembler->SmiConstant(
2213 Smi::FromInt(BailoutReason::kExpectedFixedDoubleArrayMap));
2214 assembler->CallRuntime(Runtime::kAbort, context, abort_id);
2215 result.Bind(assembler->UndefinedConstant());
2216 assembler->Goto(&return_result);
2217 }
2218 assembler->Bind(&correct_elements_map);
2219 }
2220
2221 Node* array = NonEmptyShallowClone(assembler, boilerplate, boilerplate_map,
2222 boilerplate_elements, allocation_site,
2223 capacity, FAST_DOUBLE_ELEMENTS);
2224 result.Bind(array);
2225 assembler->Goto(&return_result);
2226 }
2227
2228 assembler->Bind(&fast_elements);
2229 {
2230 assembler->Comment("fast elements path");
2231 Node* array = NonEmptyShallowClone(assembler, boilerplate, boilerplate_map,
2232 boilerplate_elements, allocation_site,
2233 capacity, FAST_ELEMENTS);
2234 result.Bind(array);
2235 assembler->Goto(&return_result);
2236 }
2237
2238 Variable length(assembler, MachineRepresentation::kTagged),
2239 elements(assembler, MachineRepresentation::kTagged);
2240 Label allocate_without_elements(assembler);
2241
2242 assembler->Bind(&cow_elements);
2243 {
2244 assembler->Comment("fixed cow path");
2245 length.Bind(assembler->LoadJSArrayLength(boilerplate));
2246 elements.Bind(boilerplate_elements);
2247
2248 assembler->Goto(&allocate_without_elements);
2249 }
2250
2251 assembler->Bind(&zero_capacity);
2252 {
2253 assembler->Comment("zero capacity path");
2254 length.Bind(zero);
2255 elements.Bind(assembler->LoadRoot(Heap::kEmptyFixedArrayRootIndex));
2256
2257 assembler->Goto(&allocate_without_elements);
2258 }
2259
2260 assembler->Bind(&allocate_without_elements);
2261 {
2262 Node* array = assembler->AllocateUninitializedJSArrayWithoutElements(
2263 FAST_ELEMENTS, boilerplate_map, length.value(), allocation_site);
2264 assembler->StoreObjectField(array, JSObject::kElementsOffset,
2265 elements.value());
2266 result.Bind(array);
2267 assembler->Goto(&return_result);
2268 }
2269
2270 assembler->Bind(&return_result);
2271 return result.value();
2272 }
2273
2274 void FastCloneShallowArrayStub::GenerateAssembly(
2275 compiler::CodeAssemblerState* state) const {
2276 typedef compiler::Node Node;
2277 typedef CodeStubAssembler::Label Label;
2278 CodeStubAssembler assembler(state);
2279
2280 Node* closure = assembler.Parameter(Descriptor::kClosure);
2281 Node* literal_index = assembler.Parameter(Descriptor::kLiteralIndex);
2282 Node* constant_elements = assembler.Parameter(Descriptor::kConstantElements);
2283 Node* context = assembler.Parameter(Descriptor::kContext);
2284 Label call_runtime(&assembler, Label::kDeferred);
2285 assembler.Return(Generate(&assembler, closure, literal_index, context,
2286 &call_runtime, allocation_site_mode()));
2287
2288 assembler.Bind(&call_runtime);
2289 {
2290 assembler.Comment("call runtime");
2291 Node* flags = assembler.SmiConstant(
2292 Smi::FromInt(ArrayLiteral::kShallowElements |
2293 (allocation_site_mode() == TRACK_ALLOCATION_SITE
2294 ? 0
2295 : ArrayLiteral::kDisableMementos)));
2296 assembler.Return(assembler.CallRuntime(Runtime::kCreateArrayLiteral,
2297 context, closure, literal_index,
2298 constant_elements, flags));
2299 }
2300 }
2301
2302 void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) { 1939 void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
2303 CreateAllocationSiteStub stub(isolate); 1940 CreateAllocationSiteStub stub(isolate);
2304 stub.GetCode(); 1941 stub.GetCode();
2305 } 1942 }
2306 1943
2307 1944
2308 void CreateWeakCellStub::GenerateAheadOfTime(Isolate* isolate) { 1945 void CreateWeakCellStub::GenerateAheadOfTime(Isolate* isolate) {
2309 CreateWeakCellStub stub(isolate); 1946 CreateWeakCellStub stub(isolate);
2310 stub.GetCode(); 1947 stub.GetCode();
2311 } 1948 }
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 } 2242 }
2606 2243
2607 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate) 2244 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
2608 : PlatformCodeStub(isolate) {} 2245 : PlatformCodeStub(isolate) {}
2609 2246
2610 InternalArrayConstructorStub::InternalArrayConstructorStub(Isolate* isolate) 2247 InternalArrayConstructorStub::InternalArrayConstructorStub(Isolate* isolate)
2611 : PlatformCodeStub(isolate) {} 2248 : PlatformCodeStub(isolate) {}
2612 2249
2613 } // namespace internal 2250 } // namespace internal
2614 } // namespace v8 2251 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/compiler/js-generic-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698