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

Side by Side Diff: src/compiler/js-inlining.cc

Issue 2666783007: [turbo] Rename CallFunction* JSOperators to Call*. (Closed)
Patch Set: Created 3 years, 10 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
« no previous file with comments | « src/compiler/js-generic-lowering.cc ('k') | src/compiler/js-inlining-heuristic.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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-inlining.h" 5 #include "src/compiler/js-inlining.h"
6 6
7 #include "src/ast/ast.h" 7 #include "src/ast/ast.h"
8 #include "src/compilation-info.h" 8 #include "src/compilation-info.h"
9 #include "src/compiler.h" 9 #include "src/compiler.h"
10 #include "src/compiler/all-nodes.h" 10 #include "src/compiler/all-nodes.h"
(...skipping 13 matching lines...) Expand all
24 namespace internal { 24 namespace internal {
25 namespace compiler { 25 namespace compiler {
26 26
27 #define TRACE(...) \ 27 #define TRACE(...) \
28 do { \ 28 do { \
29 if (FLAG_trace_turbo_inlining) PrintF(__VA_ARGS__); \ 29 if (FLAG_trace_turbo_inlining) PrintF(__VA_ARGS__); \
30 } while (false) 30 } while (false)
31 31
32 32
33 // Provides convenience accessors for the common layout of nodes having either 33 // Provides convenience accessors for the common layout of nodes having either
34 // the {JSCallFunction} or the {JSConstruct} operator. 34 // the {JSCall} or the {JSConstruct} operator.
35 class JSCallAccessor { 35 class JSCallAccessor {
36 public: 36 public:
37 explicit JSCallAccessor(Node* call) : call_(call) { 37 explicit JSCallAccessor(Node* call) : call_(call) {
38 DCHECK(call->opcode() == IrOpcode::kJSCallFunction || 38 DCHECK(call->opcode() == IrOpcode::kJSCall ||
39 call->opcode() == IrOpcode::kJSConstruct); 39 call->opcode() == IrOpcode::kJSConstruct);
40 } 40 }
41 41
42 Node* target() { 42 Node* target() {
43 // Both, {JSCallFunction} and {JSConstruct}, have same layout here. 43 // Both, {JSCall} and {JSConstruct}, have same layout here.
44 return call_->InputAt(0); 44 return call_->InputAt(0);
45 } 45 }
46 46
47 Node* receiver() { 47 Node* receiver() {
48 DCHECK_EQ(IrOpcode::kJSCallFunction, call_->opcode()); 48 DCHECK_EQ(IrOpcode::kJSCall, call_->opcode());
49 return call_->InputAt(1); 49 return call_->InputAt(1);
50 } 50 }
51 51
52 Node* new_target() { 52 Node* new_target() {
53 DCHECK_EQ(IrOpcode::kJSConstruct, call_->opcode()); 53 DCHECK_EQ(IrOpcode::kJSConstruct, call_->opcode());
54 return call_->InputAt(formal_arguments() + 1); 54 return call_->InputAt(formal_arguments() + 1);
55 } 55 }
56 56
57 Node* frame_state() { 57 Node* frame_state() {
58 // Both, {JSCallFunction} and {JSConstruct}, have frame state. 58 // Both, {JSCall} and {JSConstruct}, have frame state.
59 return NodeProperties::GetFrameStateInput(call_); 59 return NodeProperties::GetFrameStateInput(call_);
60 } 60 }
61 61
62 int formal_arguments() { 62 int formal_arguments() {
63 // Both, {JSCallFunction} and {JSConstruct}, have two extra inputs: 63 // Both, {JSCall} and {JSConstruct}, have two extra inputs:
64 // - JSConstruct: Includes target function and new target. 64 // - JSConstruct: Includes target function and new target.
65 // - JSCallFunction: Includes target function and receiver. 65 // - JSCall: Includes target function and receiver.
66 return call_->op()->ValueInputCount() - 2; 66 return call_->op()->ValueInputCount() - 2;
67 } 67 }
68 68
69 float frequency() const { 69 float frequency() const {
70 return (call_->opcode() == IrOpcode::kJSCallFunction) 70 return (call_->opcode() == IrOpcode::kJSCall)
71 ? CallFunctionParametersOf(call_->op()).frequency() 71 ? CallParametersOf(call_->op()).frequency()
72 : ConstructParametersOf(call_->op()).frequency(); 72 : ConstructParametersOf(call_->op()).frequency();
73 } 73 }
74 74
75 private: 75 private:
76 Node* call_; 76 Node* call_;
77 }; 77 };
78 78
79 Reduction JSInliner::InlineCall(Node* call, Node* new_target, Node* context, 79 Reduction JSInliner::InlineCall(Node* call, Node* new_target, Node* context,
80 Node* frame_state, Node* start, Node* end, 80 Node* frame_state, Node* start, Node* end,
81 Node* exception_target, 81 Node* exception_target,
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 } 346 }
347 347
348 } // namespace 348 } // namespace
349 349
350 350
351 Reduction JSInliner::Reduce(Node* node) { 351 Reduction JSInliner::Reduce(Node* node) {
352 if (!IrOpcode::IsInlineeOpcode(node->opcode())) return NoChange(); 352 if (!IrOpcode::IsInlineeOpcode(node->opcode())) return NoChange();
353 353
354 // This reducer can handle both normal function calls as well a constructor 354 // This reducer can handle both normal function calls as well a constructor
355 // calls whenever the target is a constant function object, as follows: 355 // calls whenever the target is a constant function object, as follows:
356 // - JSCallFunction(target:constant, receiver, args...) 356 // - JSCall(target:constant, receiver, args...)
357 // - JSConstruct(target:constant, args..., new.target) 357 // - JSConstruct(target:constant, args..., new.target)
358 HeapObjectMatcher match(node->InputAt(0)); 358 HeapObjectMatcher match(node->InputAt(0));
359 if (!match.HasValue() || !match.Value()->IsJSFunction()) return NoChange(); 359 if (!match.HasValue() || !match.Value()->IsJSFunction()) return NoChange();
360 Handle<JSFunction> function = Handle<JSFunction>::cast(match.Value()); 360 Handle<JSFunction> function = Handle<JSFunction>::cast(match.Value());
361 361
362 return ReduceJSCall(node, function); 362 return ReduceJSCall(node, function);
363 } 363 }
364 364
365 Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { 365 Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) {
366 DCHECK(IrOpcode::IsInlineeOpcode(node->opcode())); 366 DCHECK(IrOpcode::IsInlineeOpcode(node->opcode()));
(...skipping 20 matching lines...) Expand all
387 if (node->opcode() == IrOpcode::kJSConstruct && 387 if (node->opcode() == IrOpcode::kJSConstruct &&
388 IsNonConstructible(shared_info)) { 388 IsNonConstructible(shared_info)) {
389 TRACE("Not inlining %s into %s because constructor is not constructable.\n", 389 TRACE("Not inlining %s into %s because constructor is not constructable.\n",
390 shared_info->DebugName()->ToCString().get(), 390 shared_info->DebugName()->ToCString().get(),
391 info_->shared_info()->DebugName()->ToCString().get()); 391 info_->shared_info()->DebugName()->ToCString().get());
392 return NoChange(); 392 return NoChange();
393 } 393 }
394 394
395 // Class constructors are callable, but [[Call]] will raise an exception. 395 // Class constructors are callable, but [[Call]] will raise an exception.
396 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ). 396 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ).
397 if (node->opcode() == IrOpcode::kJSCallFunction && 397 if (node->opcode() == IrOpcode::kJSCall &&
398 IsClassConstructor(shared_info->kind())) { 398 IsClassConstructor(shared_info->kind())) {
399 TRACE("Not inlining %s into %s because callee is a class constructor.\n", 399 TRACE("Not inlining %s into %s because callee is a class constructor.\n",
400 shared_info->DebugName()->ToCString().get(), 400 shared_info->DebugName()->ToCString().get(),
401 info_->shared_info()->DebugName()->ToCString().get()); 401 info_->shared_info()->DebugName()->ToCString().get());
402 return NoChange(); 402 return NoChange();
403 } 403 }
404 404
405 // Function contains break points. 405 // Function contains break points.
406 if (shared_info->HasDebugInfo()) { 406 if (shared_info->HasDebugInfo()) {
407 TRACE("Not inlining %s into %s because callee may contain break points\n", 407 TRACE("Not inlining %s into %s because callee may contain break points\n",
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 graph()->NewNode(common()->Select(MachineRepresentation::kTagged), 573 graph()->NewNode(common()->Select(MachineRepresentation::kTagged),
574 check, node, create); 574 check, node, create);
575 NodeProperties::ReplaceUses(node, select, node, node, node); 575 NodeProperties::ReplaceUses(node, select, node, node, node);
576 // Fix-up inputs that have been mangled by the {ReplaceUses} call above. 576 // Fix-up inputs that have been mangled by the {ReplaceUses} call above.
577 NodeProperties::ReplaceValueInput(select, node, 1); // Fix-up input. 577 NodeProperties::ReplaceValueInput(select, node, 1); // Fix-up input.
578 NodeProperties::ReplaceValueInput(check, node, 0); // Fix-up input. 578 NodeProperties::ReplaceValueInput(check, node, 0); // Fix-up input.
579 receiver = create; // The implicit receiver. 579 receiver = create; // The implicit receiver.
580 } 580 }
581 581
582 // Swizzle the inputs of the {JSConstruct} node to look like inputs to a 582 // Swizzle the inputs of the {JSConstruct} node to look like inputs to a
583 // normal {JSCallFunction} node so that the rest of the inlining machinery 583 // normal {JSCall} node so that the rest of the inlining machinery
584 // behaves as if we were dealing with a regular function invocation. 584 // behaves as if we were dealing with a regular function invocation.
585 new_target = call.new_target(); // Retrieve new target value input. 585 new_target = call.new_target(); // Retrieve new target value input.
586 node->RemoveInput(call.formal_arguments() + 1); // Drop new target. 586 node->RemoveInput(call.formal_arguments() + 1); // Drop new target.
587 node->InsertInput(graph()->zone(), 1, receiver); 587 node->InsertInput(graph()->zone(), 1, receiver);
588 588
589 // Insert a construct stub frame into the chain of frame states. This will 589 // Insert a construct stub frame into the chain of frame states. This will
590 // reconstruct the proper frame when deoptimizing within the constructor. 590 // reconstruct the proper frame when deoptimizing within the constructor.
591 frame_state = CreateArtificialFrameState( 591 frame_state = CreateArtificialFrameState(
592 node, frame_state, call.formal_arguments(), 592 node, frame_state, call.formal_arguments(),
593 FrameStateType::kConstructStub, info.shared_info()); 593 FrameStateType::kConstructStub, info.shared_info());
594 } 594 }
595 595
596 // The inlinee specializes to the context from the JSFunction object. 596 // The inlinee specializes to the context from the JSFunction object.
597 // TODO(turbofan): We might want to load the context from the JSFunction at 597 // TODO(turbofan): We might want to load the context from the JSFunction at
598 // runtime in case we only know the SharedFunctionInfo once we have dynamic 598 // runtime in case we only know the SharedFunctionInfo once we have dynamic
599 // type feedback in the compiler. 599 // type feedback in the compiler.
600 Node* context = jsgraph()->Constant(handle(function->context())); 600 Node* context = jsgraph()->Constant(handle(function->context()));
601 601
602 // Insert a JSConvertReceiver node for sloppy callees. Note that the context 602 // Insert a JSConvertReceiver node for sloppy callees. Note that the context
603 // passed into this node has to be the callees context (loaded above). Note 603 // passed into this node has to be the callees context (loaded above). Note
604 // that the frame state passed to the JSConvertReceiver must be the frame 604 // that the frame state passed to the JSConvertReceiver must be the frame
605 // state _before_ the call; it is not necessary to fiddle with the receiver 605 // state _before_ the call; it is not necessary to fiddle with the receiver
606 // in that frame state tho, as the conversion of the receiver can be repeated 606 // in that frame state tho, as the conversion of the receiver can be repeated
607 // any number of times, it's not observable. 607 // any number of times, it's not observable.
608 if (node->opcode() == IrOpcode::kJSCallFunction && 608 if (node->opcode() == IrOpcode::kJSCall &&
609 is_sloppy(shared_info->language_mode()) && !shared_info->native()) { 609 is_sloppy(shared_info->language_mode()) && !shared_info->native()) {
610 Node* effect = NodeProperties::GetEffectInput(node); 610 Node* effect = NodeProperties::GetEffectInput(node);
611 if (NeedsConvertReceiver(call.receiver(), effect)) { 611 if (NeedsConvertReceiver(call.receiver(), effect)) {
612 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); 612 const CallParameters& p = CallParametersOf(node->op());
613 Node* frame_state_before = NodeProperties::FindFrameStateBefore(node); 613 Node* frame_state_before = NodeProperties::FindFrameStateBefore(node);
614 Node* convert = effect = graph()->NewNode( 614 Node* convert = effect = graph()->NewNode(
615 javascript()->ConvertReceiver(p.convert_mode()), call.receiver(), 615 javascript()->ConvertReceiver(p.convert_mode()), call.receiver(),
616 context, frame_state_before, effect, start); 616 context, frame_state_before, effect, start);
617 NodeProperties::ReplaceValueInput(node, convert, 1); 617 NodeProperties::ReplaceValueInput(node, convert, 1);
618 NodeProperties::ReplaceEffectInput(node, effect); 618 NodeProperties::ReplaceEffectInput(node, effect);
619 } 619 }
620 } 620 }
621 621
622 // If we are inlining a JS call at tail position then we have to pop current 622 // If we are inlining a JS call at tail position then we have to pop current
623 // frame state and its potential arguments adaptor frame state in order to 623 // frame state and its potential arguments adaptor frame state in order to
624 // make the call stack be consistent with non-inlining case. 624 // make the call stack be consistent with non-inlining case.
625 // After that we add a tail caller frame state which lets deoptimizer handle 625 // After that we add a tail caller frame state which lets deoptimizer handle
626 // the case when the outermost function inlines a tail call (it should remove 626 // the case when the outermost function inlines a tail call (it should remove
627 // potential arguments adaptor frame that belongs to outermost function when 627 // potential arguments adaptor frame that belongs to outermost function when
628 // deopt happens). 628 // deopt happens).
629 if (node->opcode() == IrOpcode::kJSCallFunction) { 629 if (node->opcode() == IrOpcode::kJSCall) {
630 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); 630 const CallParameters& p = CallParametersOf(node->op());
631 if (p.tail_call_mode() == TailCallMode::kAllow) { 631 if (p.tail_call_mode() == TailCallMode::kAllow) {
632 frame_state = CreateTailCallerFrameState(node, frame_state); 632 frame_state = CreateTailCallerFrameState(node, frame_state);
633 } 633 }
634 } 634 }
635 635
636 // Insert argument adaptor frame if required. The callees formal parameter 636 // Insert argument adaptor frame if required. The callees formal parameter
637 // count (i.e. value outputs of start node minus target, receiver, new target, 637 // count (i.e. value outputs of start node minus target, receiver, new target,
638 // arguments count and context) have to match the number of arguments passed 638 // arguments count and context) have to match the number of arguments passed
639 // to the call. 639 // to the call.
640 int parameter_count = shared_info->internal_formal_parameter_count(); 640 int parameter_count = shared_info->internal_formal_parameter_count();
(...skipping 16 matching lines...) Expand all
657 657
658 CommonOperatorBuilder* JSInliner::common() const { return jsgraph()->common(); } 658 CommonOperatorBuilder* JSInliner::common() const { return jsgraph()->common(); }
659 659
660 SimplifiedOperatorBuilder* JSInliner::simplified() const { 660 SimplifiedOperatorBuilder* JSInliner::simplified() const {
661 return jsgraph()->simplified(); 661 return jsgraph()->simplified();
662 } 662 }
663 663
664 } // namespace compiler 664 } // namespace compiler
665 } // namespace internal 665 } // namespace internal
666 } // namespace v8 666 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-generic-lowering.cc ('k') | src/compiler/js-inlining-heuristic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698