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

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

Issue 988653003: Use platform specific stubs for vector-based Load/KeyedLoad. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Included the MIPs port from Paul and Akos. Created 5 years, 9 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.cc ('k') | src/ia32/code-stubs-ia32.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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/bailout-reason.h" 7 #include "src/bailout-reason.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/field-index.h" 9 #include "src/field-index.h"
10 #include "src/hydrogen.h" 10 #include "src/hydrogen.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 HValue* map_index); 93 HValue* map_index);
94 void BuildInstallCode(HValue* js_function, HValue* shared_info); 94 void BuildInstallCode(HValue* js_function, HValue* shared_info);
95 95
96 HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map, 96 HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map,
97 HValue* iterator, 97 HValue* iterator,
98 int field_offset); 98 int field_offset);
99 void BuildInstallFromOptimizedCodeMap(HValue* js_function, 99 void BuildInstallFromOptimizedCodeMap(HValue* js_function,
100 HValue* shared_info, 100 HValue* shared_info,
101 HValue* native_context); 101 HValue* native_context);
102 102
103 // Tail calls handler found at array[map_index + 1].
104 void TailCallHandler(HValue* receiver, HValue* name, HValue* array,
105 HValue* map_index, HValue* slot, HValue* vector);
106
107 // Tail calls handler_code.
108 void TailCallHandler(HValue* receiver, HValue* name, HValue* slot,
109 HValue* vector, HValue* handler_code);
110
111 void TailCallMiss(HValue* receiver, HValue* name, HValue* slot,
112 HValue* vector, bool keyed_load);
113
114 // Handle MONOMORPHIC and POLYMORPHIC LoadIC and KeyedLoadIC cases.
115 void HandleArrayCases(HValue* array, HValue* receiver, HValue* name,
116 HValue* slot, HValue* vector, bool keyed_load);
117
118 private: 103 private:
119 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); 104 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
120 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, 105 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
121 ElementsKind kind); 106 ElementsKind kind);
122 107
123 SmartArrayPointer<HParameter*> parameters_; 108 SmartArrayPointer<HParameter*> parameters_;
124 HValue* arguments_length_; 109 HValue* arguments_length_;
125 CompilationInfoWithZone* info_; 110 CompilationInfoWithZone* info_;
126 CodeStubDescriptor descriptor_; 111 CodeStubDescriptor descriptor_;
127 HContext* context_; 112 HContext* context_;
(...skipping 1894 matching lines...) Expand 10 before | Expand all | Expand 10 after
2022 2007
2023 return Pop(); 2008 return Pop();
2024 } 2009 }
2025 2010
2026 2011
2027 Handle<Code> KeyedLoadGenericStub::GenerateCode() { 2012 Handle<Code> KeyedLoadGenericStub::GenerateCode() {
2028 return DoGenerateCode(this); 2013 return DoGenerateCode(this);
2029 } 2014 }
2030 2015
2031 2016
2032 void CodeStubGraphBuilderBase::TailCallHandler(HValue* receiver, HValue* name,
2033 HValue* array, HValue* map_index,
2034 HValue* slot, HValue* vector) {
2035 // The handler is at array[map_index + 1]. Compute this with a custom offset
2036 // to HLoadKeyed.
2037 int offset =
2038 GetDefaultHeaderSizeForElementsKind(FAST_ELEMENTS) + kPointerSize;
2039 HValue* handler_code = Add<HLoadKeyed>(
2040 array, map_index, nullptr, FAST_ELEMENTS, NEVER_RETURN_HOLE, offset);
2041 TailCallHandler(receiver, name, slot, vector, handler_code);
2042 }
2043
2044
2045 void CodeStubGraphBuilderBase::TailCallHandler(HValue* receiver, HValue* name,
2046 HValue* slot, HValue* vector,
2047 HValue* handler_code) {
2048 VectorLoadICDescriptor descriptor(isolate());
2049 HValue* op_vals[] = {context(), receiver, name, slot, vector};
2050 Add<HCallWithDescriptor>(handler_code, 0, descriptor,
2051 Vector<HValue*>(op_vals, 5), TAIL_CALL);
2052 // We never return here, it is a tail call.
2053 }
2054
2055
2056 void CodeStubGraphBuilderBase::TailCallMiss(HValue* receiver, HValue* name,
2057 HValue* slot, HValue* vector,
2058 bool keyed_load) {
2059 DCHECK(FLAG_vector_ics);
2060 Add<HTailCallThroughMegamorphicCache>(
2061 receiver, name, slot, vector,
2062 HTailCallThroughMegamorphicCache::ComputeFlags(keyed_load, true));
2063 // We never return here, it is a tail call.
2064 }
2065
2066
2067 void CodeStubGraphBuilderBase::HandleArrayCases(HValue* array, HValue* receiver,
2068 HValue* name, HValue* slot,
2069 HValue* vector,
2070 bool keyed_load) {
2071 HConstant* constant_two = Add<HConstant>(2);
2072 HConstant* constant_three = Add<HConstant>(3);
2073
2074 IfBuilder if_receiver_heap_object(this);
2075 if_receiver_heap_object.IfNot<HIsSmiAndBranch>(receiver);
2076 if_receiver_heap_object.Then();
2077 Push(AddLoadMap(receiver, nullptr));
2078 if_receiver_heap_object.Else();
2079 HConstant* heap_number_map =
2080 Add<HConstant>(isolate()->factory()->heap_number_map());
2081 Push(heap_number_map);
2082 if_receiver_heap_object.End();
2083 HValue* receiver_map = Pop();
2084
2085 HValue* start =
2086 keyed_load ? graph()->GetConstant1() : graph()->GetConstant0();
2087 HValue* weak_cell =
2088 Add<HLoadKeyed>(array, start, nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE);
2089 // Load the weak cell value. It may be Smi(0), or a map. Compare nonetheless
2090 // against the receiver_map.
2091 HValue* array_map = Add<HLoadNamedField>(weak_cell, nullptr,
2092 HObjectAccess::ForWeakCellValue());
2093
2094 IfBuilder if_correct_map(this);
2095 if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map);
2096 if_correct_map.Then();
2097 { TailCallHandler(receiver, name, array, start, slot, vector); }
2098 if_correct_map.Else();
2099 {
2100 // If our array has more elements, the ic is polymorphic. Look for the
2101 // receiver map in the rest of the array.
2102 HValue* length = AddLoadFixedArrayLength(array, nullptr);
2103 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement,
2104 constant_two);
2105 start = keyed_load ? constant_three : constant_two;
2106 HValue* key = builder.BeginBody(start, length, Token::LT);
2107 {
2108 HValue* weak_cell = Add<HLoadKeyed>(array, key, nullptr, FAST_ELEMENTS,
2109 ALLOW_RETURN_HOLE);
2110 HValue* array_map = Add<HLoadNamedField>(
2111 weak_cell, nullptr, HObjectAccess::ForWeakCellValue());
2112 IfBuilder if_correct_poly_map(this);
2113 if_correct_poly_map.If<HCompareObjectEqAndBranch>(receiver_map,
2114 array_map);
2115 if_correct_poly_map.Then();
2116 { TailCallHandler(receiver, name, array, key, slot, vector); }
2117 }
2118 builder.EndBody();
2119 }
2120 if_correct_map.End();
2121 }
2122
2123
2124 template <>
2125 HValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() {
2126 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
2127 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex);
2128 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex);
2129 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex);
2130
2131 // If the feedback is an array, then the IC is in the monomorphic or
2132 // polymorphic state.
2133 HValue* feedback =
2134 Add<HLoadKeyed>(vector, slot, nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE);
2135 IfBuilder array_checker(this);
2136 array_checker.If<HCompareMap>(feedback,
2137 isolate()->factory()->fixed_array_map());
2138 array_checker.Then();
2139 { HandleArrayCases(feedback, receiver, name, slot, vector, false); }
2140 array_checker.Else();
2141 {
2142 // Is the IC megamorphic?
2143 IfBuilder mega_checker(this);
2144 HConstant* megamorphic_symbol =
2145 Add<HConstant>(isolate()->factory()->megamorphic_symbol());
2146 mega_checker.If<HCompareObjectEqAndBranch>(feedback, megamorphic_symbol);
2147 mega_checker.Then();
2148 {
2149 // Probe the stub cache.
2150 Add<HTailCallThroughMegamorphicCache>(
2151 receiver, name, slot, vector,
2152 HTailCallThroughMegamorphicCache::ComputeFlags(false, false));
2153 }
2154 mega_checker.End();
2155 }
2156 array_checker.End();
2157
2158 TailCallMiss(receiver, name, slot, vector, false);
2159 return graph()->GetConstant0();
2160 }
2161
2162
2163 Handle<Code> VectorLoadStub::GenerateCode() { return DoGenerateCode(this); }
2164
2165
2166 template <>
2167 HValue* CodeStubGraphBuilder<VectorKeyedLoadStub>::BuildCodeStub() {
2168 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
2169 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex);
2170 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex);
2171 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex);
2172 HConstant* zero = graph()->GetConstant0();
2173
2174 // If the feedback is an array, then the IC is in the monomorphic or
2175 // polymorphic state.
2176 HValue* feedback =
2177 Add<HLoadKeyed>(vector, slot, nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE);
2178 IfBuilder array_checker(this);
2179 array_checker.If<HCompareMap>(feedback,
2180 isolate()->factory()->fixed_array_map());
2181 array_checker.Then();
2182 {
2183 // If feedback[0] is 0, then the IC has element handlers and name should be
2184 // a smi. If feedback[0] is a string, verify that it matches name.
2185 HValue* recorded_name = Add<HLoadKeyed>(feedback, zero, nullptr,
2186 FAST_ELEMENTS, ALLOW_RETURN_HOLE);
2187
2188 IfBuilder recorded_name_is_zero(this);
2189 recorded_name_is_zero.If<HCompareObjectEqAndBranch>(recorded_name, zero);
2190 recorded_name_is_zero.Then();
2191 { Add<HCheckSmi>(name); }
2192 recorded_name_is_zero.Else();
2193 {
2194 IfBuilder strings_match(this);
2195 strings_match.IfNot<HCompareObjectEqAndBranch>(name, recorded_name);
2196 strings_match.Then();
2197 TailCallMiss(receiver, name, slot, vector, true);
2198 strings_match.End();
2199 }
2200 recorded_name_is_zero.End();
2201
2202 HandleArrayCases(feedback, receiver, name, slot, vector, true);
2203 }
2204 array_checker.Else();
2205 {
2206 // Check if the IC is in megamorphic state.
2207 IfBuilder megamorphic_checker(this);
2208 HConstant* megamorphic_symbol =
2209 Add<HConstant>(isolate()->factory()->megamorphic_symbol());
2210 megamorphic_checker.If<HCompareObjectEqAndBranch>(feedback,
2211 megamorphic_symbol);
2212 megamorphic_checker.Then();
2213 {
2214 // Tail-call to the megamorphic KeyedLoadIC, treating it like a handler.
2215 Handle<Code> stub = KeyedLoadIC::ChooseMegamorphicStub(isolate());
2216 HValue* constant_stub = Add<HConstant>(stub);
2217 LoadDescriptor descriptor(isolate());
2218 HValue* op_vals[] = {context(), receiver, name};
2219 Add<HCallWithDescriptor>(constant_stub, 0, descriptor,
2220 Vector<HValue*>(op_vals, 3), TAIL_CALL);
2221 // We never return here, it is a tail call.
2222 }
2223 megamorphic_checker.End();
2224 }
2225 array_checker.End();
2226
2227 TailCallMiss(receiver, name, slot, vector, true);
2228 return zero;
2229 }
2230
2231
2232 Handle<Code> VectorKeyedLoadStub::GenerateCode() {
2233 return DoGenerateCode(this);
2234 }
2235
2236
2237 Handle<Code> MegamorphicLoadStub::GenerateCode() { 2017 Handle<Code> MegamorphicLoadStub::GenerateCode() {
2238 return DoGenerateCode(this); 2018 return DoGenerateCode(this);
2239 } 2019 }
2240 2020
2241 2021
2242 template <> 2022 template <>
2243 HValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() { 2023 HValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() {
2244 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); 2024 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
2245 HValue* name = GetParameter(LoadDescriptor::kNameIndex); 2025 HValue* name = GetParameter(LoadDescriptor::kNameIndex);
2246 2026
2247 // We shouldn't generate this when FLAG_vector_ics is true because the 2027 // We shouldn't generate this when FLAG_vector_ics is true because the
2248 // megamorphic case is handled as part of the default stub. 2028 // megamorphic case is handled as part of the default stub.
2249 DCHECK(!FLAG_vector_ics); 2029 DCHECK(!FLAG_vector_ics);
2250 2030
2251 // Probe the stub cache. 2031 // Probe the stub cache.
2252 Add<HTailCallThroughMegamorphicCache>(receiver, name); 2032 Add<HTailCallThroughMegamorphicCache>(receiver, name);
2253 2033
2254 // We never continue. 2034 // We never continue.
2255 return graph()->GetConstant0(); 2035 return graph()->GetConstant0();
2256 } 2036 }
2257 } } // namespace v8::internal 2037 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698