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

Side by Side Diff: src/compiler/js-call-reducer.cc

Issue 1476413003: Provide call counts for constructor calls, surface them as a vector IC. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Created 5 years 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/code-stubs.h ('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 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/compiler/js-graph.h" 7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/objects-inl.h" 9 #include "src/objects-inl.h"
10 #include "src/type-feedback-vector-inl.h" 10 #include "src/type-feedback-vector-inl.h"
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 // TODO(bmeurer): Also support optimizing bound functions and proxies here. 245 // TODO(bmeurer): Also support optimizing bound functions and proxies here.
246 return NoChange(); 246 return NoChange();
247 } 247 }
248 248
249 // Not much we can do if deoptimization support is disabled. 249 // Not much we can do if deoptimization support is disabled.
250 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); 250 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
251 251
252 // Extract feedback from the {node} using the CallICNexus. 252 // Extract feedback from the {node} using the CallICNexus.
253 if (!p.feedback().IsValid()) return NoChange(); 253 if (!p.feedback().IsValid()) return NoChange();
254 CallICNexus nexus(p.feedback().vector(), p.feedback().slot()); 254 CallICNexus nexus(p.feedback().vector(), p.feedback().slot());
255 Handle<Object> feedback(nexus.GetFeedback(), isolate()); 255 Handle<Object> feedback = nexus.GetCallFeedback();
256 if (feedback->IsAllocationSite()) { 256 if (feedback->IsAllocationSite()) {
257 // Retrieve the Array function from the {node}. 257 // Retrieve the Array function from the {node}.
258 Node* array_function; 258 Node* array_function;
259 Handle<Context> native_context; 259 Handle<Context> native_context;
260 if (GetNativeContext(node).ToHandle(&native_context)) { 260 if (GetNativeContext(node).ToHandle(&native_context)) {
261 array_function = jsgraph()->HeapConstant( 261 array_function = jsgraph()->HeapConstant(
262 handle(native_context->array_function(), isolate())); 262 handle(native_context->array_function(), isolate()));
263 } else { 263 } else {
264 Node* native_context = effect = graph()->NewNode( 264 Node* native_context = effect = graph()->NewNode(
265 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true), 265 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
(...skipping 14 matching lines...) Expand all
280 graph()->NewNode(common()->Deoptimize(), frame_state, effect, if_false); 280 graph()->NewNode(common()->Deoptimize(), frame_state, effect, if_false);
281 // TODO(bmeurer): This should be on the AdvancedReducer somehow. 281 // TODO(bmeurer): This should be on the AdvancedReducer somehow.
282 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); 282 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
283 control = graph()->NewNode(common()->IfTrue(), branch); 283 control = graph()->NewNode(common()->IfTrue(), branch);
284 284
285 // Turn the {node} into a {JSCreateArray} call. 285 // Turn the {node} into a {JSCreateArray} call.
286 NodeProperties::ReplaceValueInput(node, array_function, 0); 286 NodeProperties::ReplaceValueInput(node, array_function, 0);
287 NodeProperties::ReplaceEffectInput(node, effect); 287 NodeProperties::ReplaceEffectInput(node, effect);
288 NodeProperties::ReplaceControlInput(node, control); 288 NodeProperties::ReplaceControlInput(node, control);
289 return ReduceArrayConstructor(node); 289 return ReduceArrayConstructor(node);
290 } else if (feedback->IsWeakCell()) { 290 } else if (feedback->IsJSFunction()) {
291 Handle<WeakCell> cell = Handle<WeakCell>::cast(feedback); 291 Node* target_function = jsgraph()->Constant(feedback);
292 if (cell->value()->IsJSFunction()) {
293 Node* target_function =
294 jsgraph()->Constant(handle(cell->value(), isolate()));
295 292
296 // Check that the {target} is still the {target_function}. 293 // Check that the {target} is still the {target_function}.
297 Node* check = effect = 294 Node* check = effect =
298 graph()->NewNode(javascript()->StrictEqual(), target, target_function, 295 graph()->NewNode(javascript()->StrictEqual(), target, target_function,
299 context, effect, control); 296 context, effect, control);
300 Node* branch = 297 Node* branch =
301 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 298 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
302 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 299 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
303 Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, 300 Node* deoptimize =
304 effect, if_false); 301 graph()->NewNode(common()->Deoptimize(), frame_state, effect, if_false);
305 // TODO(bmeurer): This should be on the AdvancedReducer somehow. 302 // TODO(bmeurer): This should be on the AdvancedReducer somehow.
306 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); 303 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
307 control = graph()->NewNode(common()->IfTrue(), branch); 304 control = graph()->NewNode(common()->IfTrue(), branch);
308 305
309 // Specialize the JSCallFunction node to the {target_function}. 306 // Specialize the JSCallFunction node to the {target_function}.
310 NodeProperties::ReplaceValueInput(node, target_function, 0); 307 NodeProperties::ReplaceValueInput(node, target_function, 0);
311 NodeProperties::ReplaceEffectInput(node, effect); 308 NodeProperties::ReplaceEffectInput(node, effect);
312 NodeProperties::ReplaceControlInput(node, control); 309 NodeProperties::ReplaceControlInput(node, control);
313 310
314 // Try to further reduce the JSCallFunction {node}. 311 // Try to further reduce the JSCallFunction {node}.
315 Reduction const reduction = ReduceJSCallFunction(node); 312 Reduction const reduction = ReduceJSCallFunction(node);
316 return reduction.Changed() ? reduction : Changed(node); 313 return reduction.Changed() ? reduction : Changed(node);
317 }
318 } 314 }
319 return NoChange(); 315 return NoChange();
320 } 316 }
321 317
322 318
323 Reduction JSCallReducer::ReduceJSCallConstruct(Node* node) { 319 Reduction JSCallReducer::ReduceJSCallConstruct(Node* node) {
324 DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode()); 320 DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode());
325 CallConstructParameters const& p = CallConstructParametersOf(node->op()); 321 CallConstructParameters const& p = CallConstructParametersOf(node->op());
326 DCHECK_LE(2u, p.arity()); 322 DCHECK_LE(2u, p.arity());
327 int const arity = static_cast<int>(p.arity() - 2); 323 int const arity = static_cast<int>(p.arity() - 2);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 374
379 // Don't mess with other {node}s that have a constant {target}. 375 // Don't mess with other {node}s that have a constant {target}.
380 // TODO(bmeurer): Also support optimizing bound functions and proxies here. 376 // TODO(bmeurer): Also support optimizing bound functions and proxies here.
381 return NoChange(); 377 return NoChange();
382 } 378 }
383 379
384 // Not much we can do if deoptimization support is disabled. 380 // Not much we can do if deoptimization support is disabled.
385 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); 381 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
386 382
387 // TODO(mvstanton): Use ConstructICNexus here, once available. 383 // TODO(mvstanton): Use ConstructICNexus here, once available.
388 Handle<Object> feedback;
389 if (!p.feedback().IsValid()) return NoChange(); 384 if (!p.feedback().IsValid()) return NoChange();
390 feedback = handle(p.feedback().vector()->Get(p.feedback().slot()), isolate()); 385 ConstructICNexus nexus(p.feedback().vector(), p.feedback().slot());
386 Handle<Object> feedback = nexus.GetCallFeedback();
391 if (feedback->IsAllocationSite()) { 387 if (feedback->IsAllocationSite()) {
392 // The feedback is an AllocationSite, which means we have called the 388 // The feedback is an AllocationSite, which means we have called the
393 // Array function and collected transition (and pretenuring) feedback 389 // Array function and collected transition (and pretenuring) feedback
394 // for the resulting arrays. This has to be kept in sync with the 390 // for the resulting arrays. This has to be kept in sync with the
395 // implementation of the CallConstructStub. 391 // implementation of the CallConstructStub.
396 Handle<AllocationSite> site = Handle<AllocationSite>::cast(feedback); 392 Handle<AllocationSite> site = Handle<AllocationSite>::cast(feedback);
397 393
398 // Retrieve the Array function from the {node}. 394 // Retrieve the Array function from the {node}.
399 Node* array_function; 395 Node* array_function;
400 Handle<Context> native_context; 396 Handle<Context> native_context;
(...skipping 26 matching lines...) Expand all
427 NodeProperties::ReplaceEffectInput(node, effect); 423 NodeProperties::ReplaceEffectInput(node, effect);
428 NodeProperties::ReplaceControlInput(node, control); 424 NodeProperties::ReplaceControlInput(node, control);
429 NodeProperties::RemoveFrameStateInput(node, 1); 425 NodeProperties::RemoveFrameStateInput(node, 1);
430 for (int i = arity; i > 0; --i) { 426 for (int i = arity; i > 0; --i) {
431 NodeProperties::ReplaceValueInput( 427 NodeProperties::ReplaceValueInput(
432 node, NodeProperties::GetValueInput(node, i), i + 1); 428 node, NodeProperties::GetValueInput(node, i), i + 1);
433 } 429 }
434 NodeProperties::ReplaceValueInput(node, new_target, 1); 430 NodeProperties::ReplaceValueInput(node, new_target, 1);
435 NodeProperties::ChangeOp(node, javascript()->CreateArray(arity, site)); 431 NodeProperties::ChangeOp(node, javascript()->CreateArray(arity, site));
436 return Changed(node); 432 return Changed(node);
437 } else if (feedback->IsWeakCell()) { 433 } else if (feedback->IsJSFunction()) {
438 Handle<WeakCell> cell = Handle<WeakCell>::cast(feedback); 434 Node* target_function = jsgraph()->Constant(feedback);
439 if (cell->value()->IsJSFunction()) {
440 Node* target_function =
441 jsgraph()->Constant(handle(cell->value(), isolate()));
442 435
443 // Check that the {target} is still the {target_function}. 436 // Check that the {target} is still the {target_function}.
444 Node* check = effect = 437 Node* check = effect =
445 graph()->NewNode(javascript()->StrictEqual(), target, target_function, 438 graph()->NewNode(javascript()->StrictEqual(), target, target_function,
446 context, effect, control); 439 context, effect, control);
447 Node* branch = 440 Node* branch =
448 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 441 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
449 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 442 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
450 Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, 443 Node* deoptimize =
451 effect, if_false); 444 graph()->NewNode(common()->Deoptimize(), frame_state, effect, if_false);
452 // TODO(bmeurer): This should be on the AdvancedReducer somehow. 445 // TODO(bmeurer): This should be on the AdvancedReducer somehow.
453 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); 446 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
454 control = graph()->NewNode(common()->IfTrue(), branch); 447 control = graph()->NewNode(common()->IfTrue(), branch);
455 448
456 // Specialize the JSCallConstruct node to the {target_function}. 449 // Specialize the JSCallConstruct node to the {target_function}.
457 NodeProperties::ReplaceValueInput(node, target_function, 0); 450 NodeProperties::ReplaceValueInput(node, target_function, 0);
458 NodeProperties::ReplaceEffectInput(node, effect); 451 NodeProperties::ReplaceEffectInput(node, effect);
459 NodeProperties::ReplaceControlInput(node, control); 452 NodeProperties::ReplaceControlInput(node, control);
460 if (target == new_target) { 453 if (target == new_target) {
461 NodeProperties::ReplaceValueInput(node, target_function, arity + 1); 454 NodeProperties::ReplaceValueInput(node, target_function, arity + 1);
462 } 455 }
463 456
464 // Try to further reduce the JSCallConstruct {node}. 457 // Try to further reduce the JSCallConstruct {node}.
465 Reduction const reduction = ReduceJSCallConstruct(node); 458 Reduction const reduction = ReduceJSCallConstruct(node);
466 return reduction.Changed() ? reduction : Changed(node); 459 return reduction.Changed() ? reduction : Changed(node);
467 }
468 } 460 }
469 461
470 return NoChange(); 462 return NoChange();
471 } 463 }
472 464
473 465
474 MaybeHandle<Context> JSCallReducer::GetNativeContext(Node* node) { 466 MaybeHandle<Context> JSCallReducer::GetNativeContext(Node* node) {
475 Node* const context = NodeProperties::GetContextInput(node); 467 Node* const context = NodeProperties::GetContextInput(node);
476 return NodeProperties::GetSpecializationNativeContext(context, 468 return NodeProperties::GetSpecializationNativeContext(context,
477 native_context()); 469 native_context());
(...skipping 11 matching lines...) Expand all
489 } 481 }
490 482
491 483
492 JSOperatorBuilder* JSCallReducer::javascript() const { 484 JSOperatorBuilder* JSCallReducer::javascript() const {
493 return jsgraph()->javascript(); 485 return jsgraph()->javascript();
494 } 486 }
495 487
496 } // namespace compiler 488 } // namespace compiler
497 } // namespace internal 489 } // namespace internal
498 } // namespace v8 490 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/compiler/js-inlining-heuristic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698