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-intrinsic-lowering.h" | 5 #include "src/compiler/js-intrinsic-lowering.h" |
6 | 6 |
7 #include <stack> | 7 #include <stack> |
8 | 8 |
9 #include "src/compiler/access-builder.h" | 9 #include "src/compiler/access-builder.h" |
10 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 case Runtime::kInlineUnlikely: | 77 case Runtime::kInlineUnlikely: |
78 return ReduceUnLikely(node, BranchHint::kFalse); | 78 return ReduceUnLikely(node, BranchHint::kFalse); |
79 case Runtime::kInlineValueOf: | 79 case Runtime::kInlineValueOf: |
80 return ReduceValueOf(node); | 80 return ReduceValueOf(node); |
81 case Runtime::kInlineIsMinusZero: | 81 case Runtime::kInlineIsMinusZero: |
82 return ReduceIsMinusZero(node); | 82 return ReduceIsMinusZero(node); |
83 case Runtime::kInlineFixedArraySet: | 83 case Runtime::kInlineFixedArraySet: |
84 return ReduceFixedArraySet(node); | 84 return ReduceFixedArraySet(node); |
85 case Runtime::kInlineGetTypeFeedbackVector: | 85 case Runtime::kInlineGetTypeFeedbackVector: |
86 return ReduceGetTypeFeedbackVector(node); | 86 return ReduceGetTypeFeedbackVector(node); |
| 87 case Runtime::kInlineGetCallerJSFunction: |
| 88 return ReduceGetCallerJSFunction(node); |
87 default: | 89 default: |
88 break; | 90 break; |
89 } | 91 } |
90 return NoChange(); | 92 return NoChange(); |
91 } | 93 } |
92 | 94 |
93 | 95 |
94 Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) { | 96 Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) { |
95 Node* high = NodeProperties::GetValueInput(node, 0); | 97 Node* high = NodeProperties::GetValueInput(node, 0); |
96 Node* low = NodeProperties::GetValueInput(node, 1); | 98 Node* low = NodeProperties::GetValueInput(node, 1); |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 Node* effect = NodeProperties::GetEffectInput(node); | 450 Node* effect = NodeProperties::GetEffectInput(node); |
449 Node* control = NodeProperties::GetControlInput(node); | 451 Node* control = NodeProperties::GetControlInput(node); |
450 FieldAccess access = AccessBuilder::ForJSFunctionSharedFunctionInfo(); | 452 FieldAccess access = AccessBuilder::ForJSFunctionSharedFunctionInfo(); |
451 Node* load = | 453 Node* load = |
452 graph()->NewNode(simplified()->LoadField(access), func, effect, control); | 454 graph()->NewNode(simplified()->LoadField(access), func, effect, control); |
453 access = AccessBuilder::ForSharedFunctionInfoTypeFeedbackVector(); | 455 access = AccessBuilder::ForSharedFunctionInfoTypeFeedbackVector(); |
454 return Change(node, simplified()->LoadField(access), load, load, control); | 456 return Change(node, simplified()->LoadField(access), load, load, control); |
455 } | 457 } |
456 | 458 |
457 | 459 |
| 460 Reduction JSIntrinsicLowering::ReduceGetCallerJSFunction(Node* node) { |
| 461 Node* effect = NodeProperties::GetEffectInput(node); |
| 462 Node* control = NodeProperties::GetControlInput(node); |
| 463 |
| 464 if (FLAG_turbo_deoptimization) { |
| 465 Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0); |
| 466 Node* outer_frame = frame_state->InputAt(kFrameStateOuterStateInput); |
| 467 if (outer_frame->opcode() == IrOpcode::kFrameState) { |
| 468 FrameStateCallInfo state_info = |
| 469 OpParameter<FrameStateCallInfo>(outer_frame); |
| 470 switch (state_info.type()) { |
| 471 case ARGUMENTS_ADAPTOR: |
| 472 outer_frame = outer_frame->InputAt(kFrameStateOuterStateInput); |
| 473 DCHECK(outer_frame->opcode() == IrOpcode::kFrameState); |
| 474 DCHECK(OpParameter<FrameStateCallInfo>(frame_state).type() == |
| 475 JS_FRAME); |
| 476 break; |
| 477 case JS_FRAME: |
| 478 break; |
| 479 } |
| 480 // The intrinsic is inlined, return the function from the outer frame. |
| 481 Node* outer_function = outer_frame->InputAt(kFrameStateFunctionInput); |
| 482 AdvancedReducer::ReplaceWithValue(node, outer_function, effect, control); |
| 483 return Changed(outer_function); |
| 484 } |
| 485 } |
| 486 |
| 487 // TODO(danno): If FLAG_turbo_deoptimization is false then this intrinsic |
| 488 // always returns the JSFunction from the caller's frame, regardless of |
| 489 // inlining depth, which isn't correct. This implementation also forces |
| 490 // intrinsic lowering to happen after inlining, which is fine for now, but |
| 491 // eventually the frame-querying logic probably should go later, e.g. in |
| 492 // instruction selection, so that there is no phase-ordering dependency. |
| 493 FieldAccess access = AccessBuilder::ForFrameCallerFramePtr(); |
| 494 Node* fp = graph()->NewNode(machine()->LoadFramePointer()); |
| 495 Node* next_fp = |
| 496 graph()->NewNode(simplified()->LoadField(access), fp, effect, control); |
| 497 Node* candidate = graph()->NewNode( |
| 498 simplified()->LoadField(AccessBuilder::ForFrameContext()), next_fp, |
| 499 effect, control); |
| 500 |
| 501 // If JSFunction from the outermost frame is a SMI, then the frame is |
| 502 // either an arguments adapter or construct frame and needs to be skipped. |
| 503 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), candidate); |
| 504 Node* branch = graph()->NewNode(common()->Branch(), check, control); |
| 505 |
| 506 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 507 |
| 508 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 509 |
| 510 Node* next_next_fp = graph()->NewNode( |
| 511 simplified()->LoadField(AccessBuilder::ForFrameCallerFramePtr()), next_fp, |
| 512 next_fp, control); |
| 513 |
| 514 MachineType const type = static_cast<MachineType>(kMachPtr); |
| 515 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 516 next_fp = |
| 517 graph()->NewNode(common()->Phi(type, 2), next_next_fp, next_fp, control); |
| 518 return Change(node, simplified()->LoadField(AccessBuilder::ForFrameMarker()), |
| 519 next_fp, effect, control); |
| 520 } |
| 521 |
| 522 |
458 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a, | 523 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a, |
459 Node* b) { | 524 Node* b) { |
460 node->set_op(op); | 525 node->set_op(op); |
461 node->ReplaceInput(0, a); | 526 node->ReplaceInput(0, a); |
462 node->ReplaceInput(1, b); | 527 node->ReplaceInput(1, b); |
463 node->TrimInputCount(2); | 528 node->TrimInputCount(2); |
464 RelaxControls(node); | 529 RelaxControls(node); |
465 return Changed(node); | 530 return Changed(node); |
466 } | 531 } |
467 | 532 |
(...skipping 24 matching lines...) Expand all Loading... |
492 } | 557 } |
493 | 558 |
494 | 559 |
495 MachineOperatorBuilder* JSIntrinsicLowering::machine() const { | 560 MachineOperatorBuilder* JSIntrinsicLowering::machine() const { |
496 return jsgraph()->machine(); | 561 return jsgraph()->machine(); |
497 } | 562 } |
498 | 563 |
499 } // namespace compiler | 564 } // namespace compiler |
500 } // namespace internal | 565 } // namespace internal |
501 } // namespace v8 | 566 } // namespace v8 |
OLD | NEW |