| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/compiler/js-native-context-specialization.h" | 5 #include "src/compiler/js-native-context-specialization.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
| 10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
| (...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 | 566 |
| 567 // Check if we have an access o.x or o.x=v where o is the current | 567 // Check if we have an access o.x or o.x=v where o is the current |
| 568 // native contexts' global proxy, and turn that into a direct access | 568 // native contexts' global proxy, and turn that into a direct access |
| 569 // to the current native contexts' global object instead. | 569 // to the current native contexts' global object instead. |
| 570 if (receiver_maps.length() == 1) { | 570 if (receiver_maps.length() == 1) { |
| 571 Handle<Map> receiver_map = receiver_maps.first(); | 571 Handle<Map> receiver_map = receiver_maps.first(); |
| 572 if (receiver_map->IsJSGlobalProxyMap()) { | 572 if (receiver_map->IsJSGlobalProxyMap()) { |
| 573 Object* maybe_constructor = receiver_map->GetConstructor(); | 573 Object* maybe_constructor = receiver_map->GetConstructor(); |
| 574 // Detached global proxies have |null| as their constructor. | 574 // Detached global proxies have |null| as their constructor. |
| 575 if (maybe_constructor->IsJSFunction() && | 575 if (maybe_constructor->IsJSFunction() && |
| 576 JSFunction::cast(maybe_constructor)->has_context() && |
| 576 JSFunction::cast(maybe_constructor)->native_context() == | 577 JSFunction::cast(maybe_constructor)->native_context() == |
| 577 *native_context()) { | 578 *native_context()) { |
| 578 return ReduceGlobalAccess(node, receiver, value, name, access_mode, | 579 return ReduceGlobalAccess(node, receiver, value, name, access_mode, |
| 579 index); | 580 index); |
| 580 } | 581 } |
| 581 } | 582 } |
| 582 } | 583 } |
| 583 | 584 |
| 584 // Compute property access infos for the receiver maps. | 585 // Compute property access infos for the receiver maps. |
| 585 AccessInfoFactory access_info_factory(dependencies(), native_context(), | 586 AccessInfoFactory access_info_factory(dependencies(), native_context(), |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 792 | 793 |
| 793 if (flags() & kDeoptimizationEnabled) { | 794 if (flags() & kDeoptimizationEnabled) { |
| 794 // Check if we are accessing the current native contexts' global proxy. | 795 // Check if we are accessing the current native contexts' global proxy. |
| 795 HeapObjectMatcher m(receiver); | 796 HeapObjectMatcher m(receiver); |
| 796 if (m.HasValue() && m.Value().is_identical_to(global_proxy())) { | 797 if (m.HasValue() && m.Value().is_identical_to(global_proxy())) { |
| 797 // Optimize accesses to the current native contexts' global proxy. | 798 // Optimize accesses to the current native contexts' global proxy. |
| 798 return ReduceGlobalAccess(node, nullptr, value, name, access_mode); | 799 return ReduceGlobalAccess(node, nullptr, value, name, access_mode); |
| 799 } | 800 } |
| 800 } | 801 } |
| 801 | 802 |
| 802 // Check if the {nexus} reports type feedback for the IC. | |
| 803 if (nexus.IsUninitialized()) { | |
| 804 if ((flags() & kDeoptimizationEnabled) && | |
| 805 (flags() & kBailoutOnUninitialized)) { | |
| 806 return ReduceSoftDeoptimize( | |
| 807 node, | |
| 808 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); | |
| 809 } | |
| 810 return NoChange(); | |
| 811 } | |
| 812 | |
| 813 // Extract receiver maps from the IC using the {nexus}. | 803 // Extract receiver maps from the IC using the {nexus}. |
| 814 MapHandleList receiver_maps; | 804 MapHandleList receiver_maps; |
| 815 if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) { | 805 if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) { |
| 816 return NoChange(); | 806 return NoChange(); |
| 817 } else if (receiver_maps.length() == 0) { | 807 } else if (receiver_maps.length() == 0) { |
| 818 if ((flags() & kDeoptimizationEnabled) && | 808 if ((flags() & kDeoptimizationEnabled) && |
| 819 (flags() & kBailoutOnUninitialized)) { | 809 (flags() & kBailoutOnUninitialized)) { |
| 820 return ReduceSoftDeoptimize( | 810 return ReduceSoftDeoptimize( |
| 821 node, | 811 node, |
| 822 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); | 812 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1187 | 1177 |
| 1188 // Return the character from the {receiver} as single character string. | 1178 // Return the character from the {receiver} as single character string. |
| 1189 value = graph()->NewNode(simplified()->StringCharAt(), receiver, index, | 1179 value = graph()->NewNode(simplified()->StringCharAt(), receiver, index, |
| 1190 control); | 1180 control); |
| 1191 ReplaceWithValue(node, value, effect, control); | 1181 ReplaceWithValue(node, value, effect, control); |
| 1192 return Replace(value); | 1182 return Replace(value); |
| 1193 } | 1183 } |
| 1194 } | 1184 } |
| 1195 } | 1185 } |
| 1196 | 1186 |
| 1197 // Check if the {nexus} reports type feedback for the IC. | |
| 1198 if (nexus.IsUninitialized()) { | |
| 1199 if ((flags() & kDeoptimizationEnabled) && | |
| 1200 (flags() & kBailoutOnUninitialized)) { | |
| 1201 return ReduceSoftDeoptimize( | |
| 1202 node, | |
| 1203 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); | |
| 1204 } | |
| 1205 return NoChange(); | |
| 1206 } | |
| 1207 | |
| 1208 // Extract receiver maps from the {nexus}. | 1187 // Extract receiver maps from the {nexus}. |
| 1209 MapHandleList receiver_maps; | 1188 MapHandleList receiver_maps; |
| 1210 if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) { | 1189 if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) { |
| 1211 return NoChange(); | 1190 return NoChange(); |
| 1212 } else if (receiver_maps.length() == 0) { | 1191 } else if (receiver_maps.length() == 0) { |
| 1213 if ((flags() & kDeoptimizationEnabled) && | 1192 if ((flags() & kDeoptimizationEnabled) && |
| 1214 (flags() & kBailoutOnUninitialized)) { | 1193 (flags() & kBailoutOnUninitialized)) { |
| 1215 return ReduceSoftDeoptimize( | 1194 return ReduceSoftDeoptimize( |
| 1216 node, | 1195 node, |
| 1217 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); | 1196 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); |
| (...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2243 Handle<Map> receiver_map; | 2222 Handle<Map> receiver_map; |
| 2244 if (InferReceiverRootMap(receiver).ToHandle(&receiver_map)) { | 2223 if (InferReceiverRootMap(receiver).ToHandle(&receiver_map)) { |
| 2245 for (int i = receiver_maps->length(); --i >= 0;) { | 2224 for (int i = receiver_maps->length(); --i >= 0;) { |
| 2246 if (receiver_maps->at(i)->FindRootMap() != *receiver_map) { | 2225 if (receiver_maps->at(i)->FindRootMap() != *receiver_map) { |
| 2247 receiver_maps->Remove(i); | 2226 receiver_maps->Remove(i); |
| 2248 } | 2227 } |
| 2249 } | 2228 } |
| 2250 } | 2229 } |
| 2251 return true; | 2230 return true; |
| 2252 } | 2231 } |
| 2253 return false; | 2232 // Check if the {nexus} actually reports feedback for the IC. We return |
| 2233 // true if the IC is still uninitialized, which translates to a SOFT |
| 2234 // deoptimization exit in the callers. |
| 2235 return nexus.IsUninitialized(); |
| 2254 } | 2236 } |
| 2255 | 2237 |
| 2256 bool JSNativeContextSpecialization::InferReceiverMaps( | 2238 bool JSNativeContextSpecialization::InferReceiverMaps( |
| 2257 Node* receiver, Node* effect, MapHandleList* receiver_maps) { | 2239 Node* receiver, Node* effect, MapHandleList* receiver_maps) { |
| 2258 ZoneHandleSet<Map> maps; | 2240 ZoneHandleSet<Map> maps; |
| 2259 if (NodeProperties::InferReceiverMaps(receiver, effect, &maps)) { | 2241 if (NodeProperties::InferReceiverMaps(receiver, effect, &maps)) { |
| 2260 for (size_t i = 0; i < maps.size(); ++i) { | 2242 for (size_t i = 0; i < maps.size(); ++i) { |
| 2261 receiver_maps->Add(maps[i]); | 2243 receiver_maps->Add(maps[i]); |
| 2262 } | 2244 } |
| 2263 return true; | 2245 return true; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2330 return jsgraph()->javascript(); | 2312 return jsgraph()->javascript(); |
| 2331 } | 2313 } |
| 2332 | 2314 |
| 2333 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 2315 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
| 2334 return jsgraph()->simplified(); | 2316 return jsgraph()->simplified(); |
| 2335 } | 2317 } |
| 2336 | 2318 |
| 2337 } // namespace compiler | 2319 } // namespace compiler |
| 2338 } // namespace internal | 2320 } // namespace internal |
| 2339 } // namespace v8 | 2321 } // namespace v8 |
| OLD | NEW |