| 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-call-reducer.h" | 5 #include "src/compiler/js-call-reducer.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
| 10 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 node->ReplaceInput(3, frame_state); | 257 node->ReplaceInput(3, frame_state); |
| 258 node->ReplaceInput(4, effect); | 258 node->ReplaceInput(4, effect); |
| 259 node->ReplaceInput(5, control); | 259 node->ReplaceInput(5, control); |
| 260 node->TrimInputCount(6); | 260 node->TrimInputCount(6); |
| 261 NodeProperties::ChangeOp(node, javascript()->OrdinaryHasInstance()); | 261 NodeProperties::ChangeOp(node, javascript()->OrdinaryHasInstance()); |
| 262 return Changed(node); | 262 return Changed(node); |
| 263 } | 263 } |
| 264 | 264 |
| 265 namespace { | 265 namespace { |
| 266 | 266 |
| 267 // TODO(turbofan): Share with similar functionality in JSInliningHeuristic | |
| 268 // and JSNativeContextSpecialization, i.e. move to NodeProperties helper?! | |
| 269 MaybeHandle<Map> InferReceiverMap(Node* node) { | |
| 270 Node* receiver = NodeProperties::GetValueInput(node, 1); | |
| 271 Node* effect = NodeProperties::GetEffectInput(node); | |
| 272 // Check if the {node} is dominated by a CheckMaps with a single map | |
| 273 // for the {receiver}, and if so use that map for the lowering below. | |
| 274 for (Node* dominator = effect;;) { | |
| 275 if (dominator->opcode() == IrOpcode::kCheckMaps && | |
| 276 NodeProperties::IsSame(dominator->InputAt(0), receiver)) { | |
| 277 if (dominator->op()->ValueInputCount() == 2) { | |
| 278 HeapObjectMatcher m(dominator->InputAt(1)); | |
| 279 if (m.HasValue()) return Handle<Map>::cast(m.Value()); | |
| 280 } | |
| 281 return MaybeHandle<Map>(); | |
| 282 } | |
| 283 if (dominator->op()->EffectInputCount() != 1) { | |
| 284 // Didn't find any appropriate CheckMaps node. | |
| 285 return MaybeHandle<Map>(); | |
| 286 } | |
| 287 dominator = NodeProperties::GetEffectInput(dominator); | |
| 288 } | |
| 289 } | |
| 290 | |
| 291 bool CanInlineApiCall(Isolate* isolate, Node* node, | 267 bool CanInlineApiCall(Isolate* isolate, Node* node, |
| 292 Handle<FunctionTemplateInfo> function_template_info) { | 268 Handle<FunctionTemplateInfo> function_template_info) { |
| 293 DCHECK(node->opcode() == IrOpcode::kJSCall); | 269 DCHECK(node->opcode() == IrOpcode::kJSCall); |
| 294 if (V8_UNLIKELY(FLAG_runtime_stats)) return false; | 270 if (V8_UNLIKELY(FLAG_runtime_stats)) return false; |
| 295 if (function_template_info->call_code()->IsUndefined(isolate)) { | 271 if (function_template_info->call_code()->IsUndefined(isolate)) { |
| 296 return false; | 272 return false; |
| 297 } | 273 } |
| 298 CallParameters const& params = CallParametersOf(node->op()); | 274 CallParameters const& params = CallParametersOf(node->op()); |
| 299 // CallApiCallbackStub expects the target in a register, so we count it out, | 275 // CallApiCallbackStub expects the target in a register, so we count it out, |
| 300 // and counts the receiver as an implicit argument, so we count the receiver | 276 // and counts the receiver as an implicit argument, so we count the receiver |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 *holder = prototype; | 313 *holder = prototype; |
| 338 return kHolderFound; | 314 return kHolderFound; |
| 339 } | 315 } |
| 340 } | 316 } |
| 341 return kHolderNotFound; | 317 return kHolderNotFound; |
| 342 } | 318 } |
| 343 | 319 |
| 344 // ES6 section B.2.2.1.1 get Object.prototype.__proto__ | 320 // ES6 section B.2.2.1.1 get Object.prototype.__proto__ |
| 345 Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) { | 321 Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) { |
| 346 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); | 322 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); |
| 323 Node* receiver = NodeProperties::GetValueInput(node, 1); |
| 324 Node* effect = NodeProperties::GetEffectInput(node); |
| 347 | 325 |
| 348 // Try to determine the {receiver} map. | 326 // Try to determine the {receiver} map. |
| 349 Handle<Map> receiver_map; | 327 ZoneHandleSet<Map> receiver_maps; |
| 350 if (InferReceiverMap(node).ToHandle(&receiver_map)) { | 328 if (NodeProperties::InferReceiverMaps(receiver, effect, &receiver_maps)) { |
| 351 // Check if we can constant-fold the {receiver} map. | 329 Handle<Object> receiver_prototype(receiver_maps[0]->prototype(), isolate()); |
| 352 if (!receiver_map->IsJSProxyMap() && | 330 |
| 353 !receiver_map->has_hidden_prototype() && | 331 // Check if we can constant-fold the {receiver_prototype}. |
| 354 !receiver_map->is_access_check_needed()) { | 332 for (size_t i = 0; i < receiver_maps.size(); ++i) { |
| 355 Handle<Object> receiver_prototype(receiver_map->prototype(), isolate()); | 333 Handle<Map> const receiver_map = receiver_maps[i]; |
| 356 Node* value = jsgraph()->Constant(receiver_prototype); | 334 if (receiver_map->IsJSProxyMap() || |
| 357 ReplaceWithValue(node, value); | 335 receiver_map->has_hidden_prototype() || |
| 358 return Replace(value); | 336 receiver_map->is_access_check_needed() || |
| 337 receiver_map->prototype() != *receiver_prototype) { |
| 338 return NoChange(); |
| 339 } |
| 359 } | 340 } |
| 341 Node* value = jsgraph()->Constant(receiver_prototype); |
| 342 ReplaceWithValue(node, value); |
| 343 return Replace(value); |
| 360 } | 344 } |
| 361 | 345 |
| 362 return NoChange(); | 346 return NoChange(); |
| 363 } | 347 } |
| 364 | 348 |
| 365 Reduction JSCallReducer::ReduceCallApiFunction( | 349 Reduction JSCallReducer::ReduceCallApiFunction( |
| 366 Node* node, Node* target, | 350 Node* node, Node* target, |
| 367 Handle<FunctionTemplateInfo> function_template_info) { | 351 Handle<FunctionTemplateInfo> function_template_info) { |
| 368 Isolate* isolate = this->isolate(); | 352 Isolate* isolate = this->isolate(); |
| 369 CHECK(!isolate->serializer_enabled()); | 353 CHECK(!isolate->serializer_enabled()); |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 return jsgraph()->javascript(); | 792 return jsgraph()->javascript(); |
| 809 } | 793 } |
| 810 | 794 |
| 811 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { | 795 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { |
| 812 return jsgraph()->simplified(); | 796 return jsgraph()->simplified(); |
| 813 } | 797 } |
| 814 | 798 |
| 815 } // namespace compiler | 799 } // namespace compiler |
| 816 } // namespace internal | 800 } // namespace internal |
| 817 } // namespace v8 | 801 } // namespace v8 |
| OLD | NEW |