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

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: slot_count = FLAG_vector_ics ? 2 : 1. 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
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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 106
107 // Tail calls handler_code. 107 // Tail calls handler_code.
108 void TailCallHandler(HValue* receiver, HValue* name, HValue* slot, 108 void TailCallHandler(HValue* receiver, HValue* name, HValue* slot,
109 HValue* vector, HValue* handler_code); 109 HValue* vector, HValue* handler_code);
110 110
111 void TailCallMiss(HValue* receiver, HValue* name, HValue* slot, 111 void TailCallMiss(HValue* receiver, HValue* name, HValue* slot,
112 HValue* vector, bool keyed_load); 112 HValue* vector, bool keyed_load);
113 113
114 // Handle MONOMORPHIC and POLYMORPHIC LoadIC and KeyedLoadIC cases. 114 // Handle MONOMORPHIC and POLYMORPHIC LoadIC and KeyedLoadIC cases.
115 void HandleArrayCases(HValue* array, HValue* receiver, HValue* name, 115 void HandleArrayCases(HValue* array, HValue* receiver, HValue* name,
116 HValue* slot, HValue* vector, bool keyed_load); 116 HValue* slot, HValue* vector);
117 void HandleMonoCase(HValue* weak_cell, HValue* receiver, HValue* name,
Toon Verwaest 2015/03/11 17:55:01 HandleMonomorphicCase
mvstanton 2015/03/12 17:05:33 Happily all this code is dead. Removing.
118 HValue* slot, HValue* vector);
117 119
118 private: 120 private:
119 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); 121 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
120 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, 122 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
121 ElementsKind kind); 123 ElementsKind kind);
122 124
123 SmartArrayPointer<HParameter*> parameters_; 125 SmartArrayPointer<HParameter*> parameters_;
124 HValue* arguments_length_; 126 HValue* arguments_length_;
125 CompilationInfoWithZone* info_; 127 CompilationInfoWithZone* info_;
126 CodeStubDescriptor descriptor_; 128 CodeStubDescriptor descriptor_;
(...skipping 1932 matching lines...) Expand 10 before | Expand all | Expand 10 after
2059 DCHECK(FLAG_vector_ics); 2061 DCHECK(FLAG_vector_ics);
2060 Add<HTailCallThroughMegamorphicCache>( 2062 Add<HTailCallThroughMegamorphicCache>(
2061 receiver, name, slot, vector, 2063 receiver, name, slot, vector,
2062 HTailCallThroughMegamorphicCache::ComputeFlags(keyed_load, true)); 2064 HTailCallThroughMegamorphicCache::ComputeFlags(keyed_load, true));
2063 // We never return here, it is a tail call. 2065 // We never return here, it is a tail call.
2064 } 2066 }
2065 2067
2066 2068
2067 void CodeStubGraphBuilderBase::HandleArrayCases(HValue* array, HValue* receiver, 2069 void CodeStubGraphBuilderBase::HandleArrayCases(HValue* array, HValue* receiver,
2068 HValue* name, HValue* slot, 2070 HValue* name, HValue* slot,
2069 HValue* vector, 2071 HValue* vector) {
2070 bool keyed_load) {
2071 HConstant* constant_two = Add<HConstant>(2); 2072 HConstant* constant_two = Add<HConstant>(2);
2072 HConstant* constant_three = Add<HConstant>(3);
2073 2073
2074 IfBuilder if_receiver_heap_object(this); 2074 IfBuilder if_receiver_heap_object(this);
2075 if_receiver_heap_object.IfNot<HIsSmiAndBranch>(receiver); 2075 if_receiver_heap_object.IfNot<HIsSmiAndBranch>(receiver);
2076 if_receiver_heap_object.Then(); 2076 if_receiver_heap_object.Then();
2077 Push(AddLoadMap(receiver, nullptr)); 2077 Push(AddLoadMap(receiver, nullptr));
2078 if_receiver_heap_object.Else(); 2078 if_receiver_heap_object.Else();
2079 HConstant* heap_number_map = 2079 HConstant* heap_number_map =
2080 Add<HConstant>(isolate()->factory()->heap_number_map()); 2080 Add<HConstant>(isolate()->factory()->heap_number_map());
2081 Push(heap_number_map); 2081 Push(heap_number_map);
2082 if_receiver_heap_object.End(); 2082 if_receiver_heap_object.End();
2083 HValue* receiver_map = Pop(); 2083 HValue* receiver_map = Pop();
2084 2084
2085 HValue* start = 2085 HValue* start = graph()->GetConstant0();
2086 keyed_load ? graph()->GetConstant1() : graph()->GetConstant0();
2087 HValue* weak_cell = 2086 HValue* weak_cell =
2088 Add<HLoadKeyed>(array, start, nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE); 2087 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 2088 // Load the weak cell value. It may be Smi(0), or a map. Compare nonetheless
2090 // against the receiver_map. 2089 // against the receiver_map.
2091 HValue* array_map = Add<HLoadNamedField>(weak_cell, nullptr, 2090 HValue* array_map = Add<HLoadNamedField>(weak_cell, nullptr,
2092 HObjectAccess::ForWeakCellValue()); 2091 HObjectAccess::ForWeakCellValue());
2093 2092
2094 IfBuilder if_correct_map(this); 2093 IfBuilder if_correct_map(this);
2095 if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map); 2094 if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map);
2096 if_correct_map.Then(); 2095 if_correct_map.Then();
2097 { TailCallHandler(receiver, name, array, start, slot, vector); } 2096 { TailCallHandler(receiver, name, array, start, slot, vector); }
2098 if_correct_map.Else(); 2097 if_correct_map.Else();
2099 { 2098 {
2100 // If our array has more elements, the ic is polymorphic. Look for the 2099 // If our array has more elements, the ic is polymorphic. Look for the
2101 // receiver map in the rest of the array. 2100 // receiver map in the rest of the array.
2102 HValue* length = AddLoadFixedArrayLength(array, nullptr); 2101 HValue* length = AddLoadFixedArrayLength(array, nullptr);
2103 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement, 2102 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement,
2104 constant_two); 2103 constant_two);
2105 start = keyed_load ? constant_three : constant_two; 2104 start = constant_two;
2106 HValue* key = builder.BeginBody(start, length, Token::LT); 2105 HValue* key = builder.BeginBody(start, length, Token::LT);
2107 { 2106 {
2108 HValue* weak_cell = Add<HLoadKeyed>(array, key, nullptr, FAST_ELEMENTS, 2107 HValue* weak_cell = Add<HLoadKeyed>(array, key, nullptr, FAST_ELEMENTS,
2109 ALLOW_RETURN_HOLE); 2108 ALLOW_RETURN_HOLE);
2110 HValue* array_map = Add<HLoadNamedField>( 2109 HValue* array_map = Add<HLoadNamedField>(
2111 weak_cell, nullptr, HObjectAccess::ForWeakCellValue()); 2110 weak_cell, nullptr, HObjectAccess::ForWeakCellValue());
2112 IfBuilder if_correct_poly_map(this); 2111 IfBuilder if_correct_poly_map(this);
2113 if_correct_poly_map.If<HCompareObjectEqAndBranch>(receiver_map, 2112 if_correct_poly_map.If<HCompareObjectEqAndBranch>(receiver_map,
2114 array_map); 2113 array_map);
2115 if_correct_poly_map.Then(); 2114 if_correct_poly_map.Then();
2116 { TailCallHandler(receiver, name, array, key, slot, vector); } 2115 { TailCallHandler(receiver, name, array, key, slot, vector); }
2117 } 2116 }
2118 builder.EndBody(); 2117 builder.EndBody();
2119 } 2118 }
2120 if_correct_map.End(); 2119 if_correct_map.End();
2121 } 2120 }
2122 2121
2123 2122
2124 template <> 2123 void CodeStubGraphBuilderBase::HandleMonoCase(HValue* weak_cell,
2125 HValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() { 2124 HValue* receiver, HValue* name,
2126 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex); 2125 HValue* slot, HValue* vector) {
2127 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex); 2126 IfBuilder if_receiver_heap_object(this);
2128 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex); 2127 if_receiver_heap_object.IfNot<HIsSmiAndBranch>(receiver);
2129 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex); 2128 if_receiver_heap_object.Then();
2129 Push(AddLoadMap(receiver, nullptr));
2130 if_receiver_heap_object.Else();
2131 HConstant* heap_number_map =
2132 Add<HConstant>(isolate()->factory()->heap_number_map());
2133 Push(heap_number_map);
2134 if_receiver_heap_object.End();
2135 HValue* receiver_map = Pop();
2130 2136
2131 // If the feedback is an array, then the IC is in the monomorphic or 2137 // Load the weak cell value. It may be Smi(0), or a map. Compare nonetheless
2132 // polymorphic state. 2138 // against the receiver_map.
2133 HValue* feedback = 2139 HValue* array_map = Add<HLoadNamedField>(weak_cell, nullptr,
2134 Add<HLoadKeyed>(vector, slot, nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE); 2140 HObjectAccess::ForWeakCellValue());
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 2141
2158 TailCallMiss(receiver, name, slot, vector, false); 2142 IfBuilder if_correct_map(this);
2159 return graph()->GetConstant0(); 2143 if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map);
2144 if_correct_map.Then();
2145 { TailCallHandler(receiver, name, vector, slot, slot, vector); }
2146 if_correct_map.End();
2160 } 2147 }
2161 2148
2162 2149
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() { 2150 Handle<Code> MegamorphicLoadStub::GenerateCode() {
2238 return DoGenerateCode(this); 2151 return DoGenerateCode(this);
2239 } 2152 }
2240 2153
2241 2154
2242 template <> 2155 template <>
2243 HValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() { 2156 HValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() {
2244 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); 2157 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
2245 HValue* name = GetParameter(LoadDescriptor::kNameIndex); 2158 HValue* name = GetParameter(LoadDescriptor::kNameIndex);
2246 2159
2247 // We shouldn't generate this when FLAG_vector_ics is true because the 2160 // We shouldn't generate this when FLAG_vector_ics is true because the
2248 // megamorphic case is handled as part of the default stub. 2161 // megamorphic case is handled as part of the default stub.
2249 DCHECK(!FLAG_vector_ics); 2162 DCHECK(!FLAG_vector_ics);
2250 2163
2251 // Probe the stub cache. 2164 // Probe the stub cache.
2252 Add<HTailCallThroughMegamorphicCache>(receiver, name); 2165 Add<HTailCallThroughMegamorphicCache>(receiver, name);
2253 2166
2254 // We never continue. 2167 // We never continue.
2255 return graph()->GetConstant0(); 2168 return graph()->GetConstant0();
2256 } 2169 }
2257 } } // namespace v8::internal 2170 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/ia32/code-stubs-ia32.cc » ('j') | src/ia32/code-stubs-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698