OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |