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

Side by Side Diff: src/compiler/js-call-reducer.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-call-reducer.h ('k') | src/compiler/js-generic-lowering.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 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"
11 #include "src/compiler/linkage.h" 11 #include "src/compiler/linkage.h"
12 #include "src/compiler/node-matchers.h" 12 #include "src/compiler/node-matchers.h"
13 #include "src/compiler/simplified-operator.h" 13 #include "src/compiler/simplified-operator.h"
14 #include "src/objects-inl.h" 14 #include "src/objects-inl.h"
15 #include "src/type-feedback-vector-inl.h" 15 #include "src/type-feedback-vector-inl.h"
16 16
17 namespace v8 { 17 namespace v8 {
18 namespace internal { 18 namespace internal {
19 namespace compiler { 19 namespace compiler {
20 20
21 Reduction JSCallReducer::Reduce(Node* node) { 21 Reduction JSCallReducer::Reduce(Node* node) {
22 switch (node->opcode()) { 22 switch (node->opcode()) {
23 case IrOpcode::kJSConstruct: 23 case IrOpcode::kJSConstruct:
24 return ReduceJSConstruct(node); 24 return ReduceJSConstruct(node);
25 case IrOpcode::kJSConstructWithSpread: 25 case IrOpcode::kJSConstructWithSpread:
26 return ReduceJSConstructWithSpread(node); 26 return ReduceJSConstructWithSpread(node);
27 case IrOpcode::kJSCallFunction: 27 case IrOpcode::kJSCall:
28 return ReduceJSCallFunction(node); 28 return ReduceJSCall(node);
29 default: 29 default:
30 break; 30 break;
31 } 31 }
32 return NoChange(); 32 return NoChange();
33 } 33 }
34 34
35 35
36 // ES6 section 22.1.1 The Array Constructor 36 // ES6 section 22.1.1 The Array Constructor
37 Reduction JSCallReducer::ReduceArrayConstructor(Node* node) { 37 Reduction JSCallReducer::ReduceArrayConstructor(Node* node) {
38 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); 38 DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
39 Node* target = NodeProperties::GetValueInput(node, 0); 39 Node* target = NodeProperties::GetValueInput(node, 0);
40 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); 40 CallParameters const& p = CallParametersOf(node->op());
41 41
42 // Check if we have an allocation site from the CallIC. 42 // Check if we have an allocation site from the CallIC.
43 Handle<AllocationSite> site; 43 Handle<AllocationSite> site;
44 if (p.feedback().IsValid()) { 44 if (p.feedback().IsValid()) {
45 CallICNexus nexus(p.feedback().vector(), p.feedback().slot()); 45 CallICNexus nexus(p.feedback().vector(), p.feedback().slot());
46 Handle<Object> feedback(nexus.GetFeedback(), isolate()); 46 Handle<Object> feedback(nexus.GetFeedback(), isolate());
47 if (feedback->IsAllocationSite()) { 47 if (feedback->IsAllocationSite()) {
48 site = Handle<AllocationSite>::cast(feedback); 48 site = Handle<AllocationSite>::cast(feedback);
49 } 49 }
50 } 50 }
51 51
52 // Turn the {node} into a {JSCreateArray} call. 52 // Turn the {node} into a {JSCreateArray} call.
53 DCHECK_LE(2u, p.arity()); 53 DCHECK_LE(2u, p.arity());
54 size_t const arity = p.arity() - 2; 54 size_t const arity = p.arity() - 2;
55 NodeProperties::ReplaceValueInput(node, target, 0); 55 NodeProperties::ReplaceValueInput(node, target, 0);
56 NodeProperties::ReplaceValueInput(node, target, 1); 56 NodeProperties::ReplaceValueInput(node, target, 1);
57 // TODO(bmeurer): We might need to propagate the tail call mode to 57 // TODO(bmeurer): We might need to propagate the tail call mode to
58 // the JSCreateArray operator, because an Array call in tail call 58 // the JSCreateArray operator, because an Array call in tail call
59 // position must always properly consume the parent stack frame. 59 // position must always properly consume the parent stack frame.
60 NodeProperties::ChangeOp(node, javascript()->CreateArray(arity, site)); 60 NodeProperties::ChangeOp(node, javascript()->CreateArray(arity, site));
61 return Changed(node); 61 return Changed(node);
62 } 62 }
63 63
64 64
65 // ES6 section 20.1.1 The Number Constructor 65 // ES6 section 20.1.1 The Number Constructor
66 Reduction JSCallReducer::ReduceNumberConstructor(Node* node) { 66 Reduction JSCallReducer::ReduceNumberConstructor(Node* node) {
67 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); 67 DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
68 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); 68 CallParameters const& p = CallParametersOf(node->op());
69 69
70 // Turn the {node} into a {JSToNumber} call. 70 // Turn the {node} into a {JSToNumber} call.
71 DCHECK_LE(2u, p.arity()); 71 DCHECK_LE(2u, p.arity());
72 Node* value = (p.arity() == 2) ? jsgraph()->ZeroConstant() 72 Node* value = (p.arity() == 2) ? jsgraph()->ZeroConstant()
73 : NodeProperties::GetValueInput(node, 2); 73 : NodeProperties::GetValueInput(node, 2);
74 NodeProperties::ReplaceValueInputs(node, value); 74 NodeProperties::ReplaceValueInputs(node, value);
75 NodeProperties::ChangeOp(node, javascript()->ToNumber()); 75 NodeProperties::ChangeOp(node, javascript()->ToNumber());
76 return Changed(node); 76 return Changed(node);
77 } 77 }
78 78
79 79
80 // ES6 section 19.2.3.1 Function.prototype.apply ( thisArg, argArray ) 80 // ES6 section 19.2.3.1 Function.prototype.apply ( thisArg, argArray )
81 Reduction JSCallReducer::ReduceFunctionPrototypeApply(Node* node) { 81 Reduction JSCallReducer::ReduceFunctionPrototypeApply(Node* node) {
82 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); 82 DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
83 Node* target = NodeProperties::GetValueInput(node, 0); 83 Node* target = NodeProperties::GetValueInput(node, 0);
84 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); 84 CallParameters const& p = CallParametersOf(node->op());
85 // Tail calls to Function.prototype.apply are not properly supported 85 // Tail calls to Function.prototype.apply are not properly supported
86 // down the pipeline, so we disable this optimization completely for 86 // down the pipeline, so we disable this optimization completely for
87 // tail calls (for now). 87 // tail calls (for now).
88 if (p.tail_call_mode() == TailCallMode::kAllow) return NoChange(); 88 if (p.tail_call_mode() == TailCallMode::kAllow) return NoChange();
89 Handle<JSFunction> apply = 89 Handle<JSFunction> apply =
90 Handle<JSFunction>::cast(HeapObjectMatcher(target).Value()); 90 Handle<JSFunction>::cast(HeapObjectMatcher(target).Value());
91 size_t arity = p.arity(); 91 size_t arity = p.arity();
92 DCHECK_LE(2u, arity); 92 DCHECK_LE(2u, arity);
93 ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny; 93 ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny;
94 if (arity == 2) { 94 if (arity == 2) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 node->InsertInput(graph()->zone(), static_cast<int>(arity), 168 node->InsertInput(graph()->zone(), static_cast<int>(arity),
169 parameters->InputAt(i)); 169 parameters->InputAt(i));
170 ++arity; 170 ++arity;
171 } 171 }
172 // Drop the {target} from the {node}. 172 // Drop the {target} from the {node}.
173 node->RemoveInput(0); 173 node->RemoveInput(0);
174 --arity; 174 --arity;
175 } else { 175 } else {
176 return NoChange(); 176 return NoChange();
177 } 177 }
178 // Change {node} to the new {JSCallFunction} operator. 178 // Change {node} to the new {JSCall} operator.
179 NodeProperties::ChangeOp( 179 NodeProperties::ChangeOp(
180 node, javascript()->CallFunction(arity, p.frequency(), VectorSlotPair(), 180 node,
181 convert_mode, p.tail_call_mode())); 181 javascript()->Call(arity, p.frequency(), VectorSlotPair(), convert_mode,
182 p.tail_call_mode()));
182 // Change context of {node} to the Function.prototype.apply context, 183 // Change context of {node} to the Function.prototype.apply context,
183 // to ensure any exception is thrown in the correct context. 184 // to ensure any exception is thrown in the correct context.
184 NodeProperties::ReplaceContextInput( 185 NodeProperties::ReplaceContextInput(
185 node, jsgraph()->HeapConstant(handle(apply->context(), isolate()))); 186 node, jsgraph()->HeapConstant(handle(apply->context(), isolate())));
186 // Try to further reduce the JSCallFunction {node}. 187 // Try to further reduce the JSCall {node}.
187 Reduction const reduction = ReduceJSCallFunction(node); 188 Reduction const reduction = ReduceJSCall(node);
188 return reduction.Changed() ? reduction : Changed(node); 189 return reduction.Changed() ? reduction : Changed(node);
189 } 190 }
190 191
191 192
192 // ES6 section 19.2.3.3 Function.prototype.call (thisArg, ...args) 193 // ES6 section 19.2.3.3 Function.prototype.call (thisArg, ...args)
193 Reduction JSCallReducer::ReduceFunctionPrototypeCall(Node* node) { 194 Reduction JSCallReducer::ReduceFunctionPrototypeCall(Node* node) {
194 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); 195 DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
195 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); 196 CallParameters const& p = CallParametersOf(node->op());
196 Handle<JSFunction> call = Handle<JSFunction>::cast( 197 Handle<JSFunction> call = Handle<JSFunction>::cast(
197 HeapObjectMatcher(NodeProperties::GetValueInput(node, 0)).Value()); 198 HeapObjectMatcher(NodeProperties::GetValueInput(node, 0)).Value());
198 // Change context of {node} to the Function.prototype.call context, 199 // Change context of {node} to the Function.prototype.call context,
199 // to ensure any exception is thrown in the correct context. 200 // to ensure any exception is thrown in the correct context.
200 NodeProperties::ReplaceContextInput( 201 NodeProperties::ReplaceContextInput(
201 node, jsgraph()->HeapConstant(handle(call->context(), isolate()))); 202 node, jsgraph()->HeapConstant(handle(call->context(), isolate())));
202 // Remove the target from {node} and use the receiver as target instead, and 203 // Remove the target from {node} and use the receiver as target instead, and
203 // the thisArg becomes the new target. If thisArg was not provided, insert 204 // the thisArg becomes the new target. If thisArg was not provided, insert
204 // undefined instead. 205 // undefined instead.
205 size_t arity = p.arity(); 206 size_t arity = p.arity();
206 DCHECK_LE(2u, arity); 207 DCHECK_LE(2u, arity);
207 ConvertReceiverMode convert_mode; 208 ConvertReceiverMode convert_mode;
208 if (arity == 2) { 209 if (arity == 2) {
209 // The thisArg was not provided, use undefined as receiver. 210 // The thisArg was not provided, use undefined as receiver.
210 convert_mode = ConvertReceiverMode::kNullOrUndefined; 211 convert_mode = ConvertReceiverMode::kNullOrUndefined;
211 node->ReplaceInput(0, node->InputAt(1)); 212 node->ReplaceInput(0, node->InputAt(1));
212 node->ReplaceInput(1, jsgraph()->UndefinedConstant()); 213 node->ReplaceInput(1, jsgraph()->UndefinedConstant());
213 } else { 214 } else {
214 // Just remove the target, which is the first value input. 215 // Just remove the target, which is the first value input.
215 convert_mode = ConvertReceiverMode::kAny; 216 convert_mode = ConvertReceiverMode::kAny;
216 node->RemoveInput(0); 217 node->RemoveInput(0);
217 --arity; 218 --arity;
218 } 219 }
219 NodeProperties::ChangeOp( 220 NodeProperties::ChangeOp(
220 node, javascript()->CallFunction(arity, p.frequency(), VectorSlotPair(), 221 node,
221 convert_mode, p.tail_call_mode())); 222 javascript()->Call(arity, p.frequency(), VectorSlotPair(), convert_mode,
222 // Try to further reduce the JSCallFunction {node}. 223 p.tail_call_mode()));
223 Reduction const reduction = ReduceJSCallFunction(node); 224 // Try to further reduce the JSCall {node}.
225 Reduction const reduction = ReduceJSCall(node);
224 return reduction.Changed() ? reduction : Changed(node); 226 return reduction.Changed() ? reduction : Changed(node);
225 } 227 }
226 228
227 // ES6 section 19.2.3.6 Function.prototype [ @@hasInstance ] (V) 229 // ES6 section 19.2.3.6 Function.prototype [ @@hasInstance ] (V)
228 Reduction JSCallReducer::ReduceFunctionPrototypeHasInstance(Node* node) { 230 Reduction JSCallReducer::ReduceFunctionPrototypeHasInstance(Node* node) {
229 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); 231 DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
230 Node* receiver = NodeProperties::GetValueInput(node, 1); 232 Node* receiver = NodeProperties::GetValueInput(node, 1);
231 Node* object = (node->op()->ValueInputCount() >= 3) 233 Node* object = (node->op()->ValueInputCount() >= 3)
232 ? NodeProperties::GetValueInput(node, 2) 234 ? NodeProperties::GetValueInput(node, 2)
233 : jsgraph()->UndefinedConstant(); 235 : jsgraph()->UndefinedConstant();
234 Node* context = NodeProperties::GetContextInput(node); 236 Node* context = NodeProperties::GetContextInput(node);
235 Node* frame_state = NodeProperties::GetFrameStateInput(node); 237 Node* frame_state = NodeProperties::GetFrameStateInput(node);
236 Node* effect = NodeProperties::GetEffectInput(node); 238 Node* effect = NodeProperties::GetEffectInput(node);
237 Node* control = NodeProperties::GetControlInput(node); 239 Node* control = NodeProperties::GetControlInput(node);
238 240
239 // TODO(turbofan): If JSOrdinaryToInstance raises an exception, the 241 // TODO(turbofan): If JSOrdinaryToInstance raises an exception, the
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 if (dominator->op()->EffectInputCount() != 1) { 276 if (dominator->op()->EffectInputCount() != 1) {
275 // Didn't find any appropriate CheckMaps node. 277 // Didn't find any appropriate CheckMaps node.
276 return MaybeHandle<Map>(); 278 return MaybeHandle<Map>();
277 } 279 }
278 dominator = NodeProperties::GetEffectInput(dominator); 280 dominator = NodeProperties::GetEffectInput(dominator);
279 } 281 }
280 } 282 }
281 283
282 bool CanInlineApiCall(Isolate* isolate, Node* node, 284 bool CanInlineApiCall(Isolate* isolate, Node* node,
283 Handle<FunctionTemplateInfo> function_template_info) { 285 Handle<FunctionTemplateInfo> function_template_info) {
284 DCHECK(node->opcode() == IrOpcode::kJSCallFunction); 286 DCHECK(node->opcode() == IrOpcode::kJSCall);
285 if (V8_UNLIKELY(FLAG_runtime_stats)) return false; 287 if (V8_UNLIKELY(FLAG_runtime_stats)) return false;
286 if (function_template_info->call_code()->IsUndefined(isolate)) { 288 if (function_template_info->call_code()->IsUndefined(isolate)) {
287 return false; 289 return false;
288 } 290 }
289 CallFunctionParameters const& params = CallFunctionParametersOf(node->op()); 291 CallParameters const& params = CallParametersOf(node->op());
290 // CallApiCallbackStub expects the target in a register, so we count it out, 292 // CallApiCallbackStub expects the target in a register, so we count it out,
291 // and counts the receiver as an implicit argument, so we count the receiver 293 // and counts the receiver as an implicit argument, so we count the receiver
292 // out too. 294 // out too.
293 int const argc = static_cast<int>(params.arity()) - 2; 295 int const argc = static_cast<int>(params.arity()) - 2;
294 if (argc > CallApiCallbackStub::kArgMax || !params.feedback().IsValid()) { 296 if (argc > CallApiCallbackStub::kArgMax || !params.feedback().IsValid()) {
295 return false; 297 return false;
296 } 298 }
297 HeapObjectMatcher receiver(NodeProperties::GetValueInput(node, 1)); 299 HeapObjectMatcher receiver(NodeProperties::GetValueInput(node, 1));
298 if (!receiver.HasValue()) { 300 if (!receiver.HasValue()) {
299 return false; 301 return false;
(...skipping 27 matching lines...) Expand all
327 if (expected_receiver_type->IsTemplateFor(*object_map)) { 329 if (expected_receiver_type->IsTemplateFor(*object_map)) {
328 *holder = prototype; 330 *holder = prototype;
329 return kHolderFound; 331 return kHolderFound;
330 } 332 }
331 } 333 }
332 return kHolderNotFound; 334 return kHolderNotFound;
333 } 335 }
334 336
335 // ES6 section B.2.2.1.1 get Object.prototype.__proto__ 337 // ES6 section B.2.2.1.1 get Object.prototype.__proto__
336 Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) { 338 Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) {
337 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); 339 DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
338 340
339 // Try to determine the {receiver} map. 341 // Try to determine the {receiver} map.
340 Handle<Map> receiver_map; 342 Handle<Map> receiver_map;
341 if (InferReceiverMap(node).ToHandle(&receiver_map)) { 343 if (InferReceiverMap(node).ToHandle(&receiver_map)) {
342 // Check if we can constant-fold the {receiver} map. 344 // Check if we can constant-fold the {receiver} map.
343 if (!receiver_map->IsJSProxyMap() && 345 if (!receiver_map->IsJSProxyMap() &&
344 !receiver_map->has_hidden_prototype() && 346 !receiver_map->has_hidden_prototype() &&
345 !receiver_map->is_access_check_needed()) { 347 !receiver_map->is_access_check_needed()) {
346 Handle<Object> receiver_prototype(receiver_map->prototype(), isolate()); 348 Handle<Object> receiver_prototype(receiver_map->prototype(), isolate());
347 Node* value = jsgraph()->Constant(receiver_prototype); 349 Node* value = jsgraph()->Constant(receiver_prototype);
(...skipping 13 matching lines...) Expand all
361 HeapObjectMatcher m(target); 363 HeapObjectMatcher m(target);
362 DCHECK(m.HasValue() && m.Value()->IsJSFunction()); 364 DCHECK(m.HasValue() && m.Value()->IsJSFunction());
363 if (!CanInlineApiCall(isolate, node, function_template_info)) { 365 if (!CanInlineApiCall(isolate, node, function_template_info)) {
364 return NoChange(); 366 return NoChange();
365 } 367 }
366 Handle<CallHandlerInfo> call_handler_info( 368 Handle<CallHandlerInfo> call_handler_info(
367 handle(CallHandlerInfo::cast(function_template_info->call_code()))); 369 handle(CallHandlerInfo::cast(function_template_info->call_code())));
368 Handle<Object> data(call_handler_info->data(), isolate); 370 Handle<Object> data(call_handler_info->data(), isolate);
369 371
370 Node* receiver_node = NodeProperties::GetValueInput(node, 1); 372 Node* receiver_node = NodeProperties::GetValueInput(node, 1);
371 CallFunctionParameters const& params = CallFunctionParametersOf(node->op()); 373 CallParameters const& params = CallParametersOf(node->op());
372 374
373 Handle<HeapObject> receiver = HeapObjectMatcher(receiver_node).Value(); 375 Handle<HeapObject> receiver = HeapObjectMatcher(receiver_node).Value();
374 bool const receiver_is_undefined = receiver->IsUndefined(isolate); 376 bool const receiver_is_undefined = receiver->IsUndefined(isolate);
375 if (receiver_is_undefined) { 377 if (receiver_is_undefined) {
376 receiver = handle(Handle<JSFunction>::cast(m.Value())->global_proxy()); 378 receiver = handle(Handle<JSFunction>::cast(m.Value())->global_proxy());
377 } else { 379 } else {
378 DCHECK(receiver->map()->IsJSObjectMap() && 380 DCHECK(receiver->map()->IsJSObjectMap() &&
379 !receiver->map()->is_access_check_needed()); 381 !receiver->map()->is_access_check_needed());
380 } 382 }
381 383
(...skipping 27 matching lines...) Expand all
409 // CallApiCallbackStub's register arguments: code, target, call data, holder, 411 // CallApiCallbackStub's register arguments: code, target, call data, holder,
410 // function address. 412 // function address.
411 node->InsertInput(zone, 0, jsgraph()->HeapConstant(stub.GetCode())); 413 node->InsertInput(zone, 0, jsgraph()->HeapConstant(stub.GetCode()));
412 node->InsertInput(zone, 2, jsgraph()->Constant(data)); 414 node->InsertInput(zone, 2, jsgraph()->Constant(data));
413 node->InsertInput(zone, 3, holder_node); 415 node->InsertInput(zone, 3, holder_node);
414 node->InsertInput(zone, 4, jsgraph()->ExternalConstant(function_reference)); 416 node->InsertInput(zone, 4, jsgraph()->ExternalConstant(function_reference));
415 NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 417 NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
416 return Changed(node); 418 return Changed(node);
417 } 419 }
418 420
419 Reduction JSCallReducer::ReduceJSCallFunction(Node* node) { 421 Reduction JSCallReducer::ReduceJSCall(Node* node) {
420 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); 422 DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
421 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); 423 CallParameters const& p = CallParametersOf(node->op());
422 Node* target = NodeProperties::GetValueInput(node, 0); 424 Node* target = NodeProperties::GetValueInput(node, 0);
423 Node* control = NodeProperties::GetControlInput(node); 425 Node* control = NodeProperties::GetControlInput(node);
424 Node* effect = NodeProperties::GetEffectInput(node); 426 Node* effect = NodeProperties::GetEffectInput(node);
425 427
426 // Try to specialize JSCallFunction {node}s with constant {target}s. 428 // Try to specialize JSCall {node}s with constant {target}s.
427 HeapObjectMatcher m(target); 429 HeapObjectMatcher m(target);
428 if (m.HasValue()) { 430 if (m.HasValue()) {
429 if (m.Value()->IsJSFunction()) { 431 if (m.Value()->IsJSFunction()) {
430 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value()); 432 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
431 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); 433 Handle<SharedFunctionInfo> shared(function->shared(), isolate());
432 434
433 // Raise a TypeError if the {target} is a "classConstructor". 435 // Raise a TypeError if the {target} is a "classConstructor".
434 if (IsClassConstructor(shared->kind())) { 436 if (IsClassConstructor(shared->kind())) {
435 NodeProperties::ReplaceValueInputs(node, target); 437 NodeProperties::ReplaceValueInputs(node, target);
436 NodeProperties::ChangeOp( 438 NodeProperties::ChangeOp(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 handle(FunctionTemplateInfo::cast(shared->function_data()))); 471 handle(FunctionTemplateInfo::cast(shared->function_data())));
470 } 472 }
471 } else if (m.Value()->IsJSBoundFunction()) { 473 } else if (m.Value()->IsJSBoundFunction()) {
472 Handle<JSBoundFunction> function = 474 Handle<JSBoundFunction> function =
473 Handle<JSBoundFunction>::cast(m.Value()); 475 Handle<JSBoundFunction>::cast(m.Value());
474 Handle<JSReceiver> bound_target_function( 476 Handle<JSReceiver> bound_target_function(
475 function->bound_target_function(), isolate()); 477 function->bound_target_function(), isolate());
476 Handle<Object> bound_this(function->bound_this(), isolate()); 478 Handle<Object> bound_this(function->bound_this(), isolate());
477 Handle<FixedArray> bound_arguments(function->bound_arguments(), 479 Handle<FixedArray> bound_arguments(function->bound_arguments(),
478 isolate()); 480 isolate());
479 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); 481 CallParameters const& p = CallParametersOf(node->op());
480 ConvertReceiverMode const convert_mode = 482 ConvertReceiverMode const convert_mode =
481 (bound_this->IsNullOrUndefined(isolate())) 483 (bound_this->IsNullOrUndefined(isolate()))
482 ? ConvertReceiverMode::kNullOrUndefined 484 ? ConvertReceiverMode::kNullOrUndefined
483 : ConvertReceiverMode::kNotNullOrUndefined; 485 : ConvertReceiverMode::kNotNullOrUndefined;
484 size_t arity = p.arity(); 486 size_t arity = p.arity();
485 DCHECK_LE(2u, arity); 487 DCHECK_LE(2u, arity);
486 // Patch {node} to use [[BoundTargetFunction]] and [[BoundThis]]. 488 // Patch {node} to use [[BoundTargetFunction]] and [[BoundThis]].
487 NodeProperties::ReplaceValueInput( 489 NodeProperties::ReplaceValueInput(
488 node, jsgraph()->Constant(bound_target_function), 0); 490 node, jsgraph()->Constant(bound_target_function), 0);
489 NodeProperties::ReplaceValueInput(node, jsgraph()->Constant(bound_this), 491 NodeProperties::ReplaceValueInput(node, jsgraph()->Constant(bound_this),
490 1); 492 1);
491 // Insert the [[BoundArguments]] for {node}. 493 // Insert the [[BoundArguments]] for {node}.
492 for (int i = 0; i < bound_arguments->length(); ++i) { 494 for (int i = 0; i < bound_arguments->length(); ++i) {
493 node->InsertInput( 495 node->InsertInput(
494 graph()->zone(), i + 2, 496 graph()->zone(), i + 2,
495 jsgraph()->Constant(handle(bound_arguments->get(i), isolate()))); 497 jsgraph()->Constant(handle(bound_arguments->get(i), isolate())));
496 arity++; 498 arity++;
497 } 499 }
498 NodeProperties::ChangeOp(node, javascript()->CallFunction( 500 NodeProperties::ChangeOp(
499 arity, p.frequency(), VectorSlotPair(), 501 node,
500 convert_mode, p.tail_call_mode())); 502 javascript()->Call(arity, p.frequency(), VectorSlotPair(),
501 // Try to further reduce the JSCallFunction {node}. 503 convert_mode, p.tail_call_mode()));
502 Reduction const reduction = ReduceJSCallFunction(node); 504 // Try to further reduce the JSCall {node}.
505 Reduction const reduction = ReduceJSCall(node);
503 return reduction.Changed() ? reduction : Changed(node); 506 return reduction.Changed() ? reduction : Changed(node);
504 } 507 }
505 508
506 // Don't mess with other {node}s that have a constant {target}. 509 // Don't mess with other {node}s that have a constant {target}.
507 // TODO(bmeurer): Also support proxies here. 510 // TODO(bmeurer): Also support proxies here.
508 return NoChange(); 511 return NoChange();
509 } 512 }
510 513
511 // Extract feedback from the {node} using the CallICNexus. 514 // Extract feedback from the {node} using the CallICNexus.
512 if (!p.feedback().IsValid()) return NoChange(); 515 if (!p.feedback().IsValid()) return NoChange();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 if (cell->value()->IsJSFunction()) { 562 if (cell->value()->IsJSFunction()) {
560 Node* target_function = 563 Node* target_function =
561 jsgraph()->Constant(handle(cell->value(), isolate())); 564 jsgraph()->Constant(handle(cell->value(), isolate()));
562 565
563 // Check that the {target} is still the {target_function}. 566 // Check that the {target} is still the {target_function}.
564 Node* check = graph()->NewNode(simplified()->ReferenceEqual(), target, 567 Node* check = graph()->NewNode(simplified()->ReferenceEqual(), target,
565 target_function); 568 target_function);
566 effect = 569 effect =
567 graph()->NewNode(simplified()->CheckIf(), check, effect, control); 570 graph()->NewNode(simplified()->CheckIf(), check, effect, control);
568 571
569 // Specialize the JSCallFunction node to the {target_function}. 572 // Specialize the JSCall node to the {target_function}.
570 NodeProperties::ReplaceValueInput(node, target_function, 0); 573 NodeProperties::ReplaceValueInput(node, target_function, 0);
571 NodeProperties::ReplaceEffectInput(node, effect); 574 NodeProperties::ReplaceEffectInput(node, effect);
572 575
573 // Try to further reduce the JSCallFunction {node}. 576 // Try to further reduce the JSCall {node}.
574 Reduction const reduction = ReduceJSCallFunction(node); 577 Reduction const reduction = ReduceJSCall(node);
575 return reduction.Changed() ? reduction : Changed(node); 578 return reduction.Changed() ? reduction : Changed(node);
576 } 579 }
577 } 580 }
578 return NoChange(); 581 return NoChange();
579 } 582 }
580 583
581 Reduction JSCallReducer::ReduceJSConstruct(Node* node) { 584 Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
582 DCHECK_EQ(IrOpcode::kJSConstruct, node->opcode()); 585 DCHECK_EQ(IrOpcode::kJSConstruct, node->opcode());
583 ConstructParameters const& p = ConstructParametersOf(node->op()); 586 ConstructParameters const& p = ConstructParametersOf(node->op());
584 DCHECK_LE(2u, p.arity()); 587 DCHECK_LE(2u, p.arity());
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 return jsgraph()->javascript(); 783 return jsgraph()->javascript();
781 } 784 }
782 785
783 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { 786 SimplifiedOperatorBuilder* JSCallReducer::simplified() const {
784 return jsgraph()->simplified(); 787 return jsgraph()->simplified();
785 } 788 }
786 789
787 } // namespace compiler 790 } // namespace compiler
788 } // namespace internal 791 } // namespace internal
789 } // namespace v8 792 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-call-reducer.h ('k') | src/compiler/js-generic-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698