OLD | NEW |
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/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/ast/compile-time-value.h" | 7 #include "src/ast/compile-time-value.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
(...skipping 2412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2423 Node* new_callee = NewNode(op, callee, source, function, language, | 2423 Node* new_callee = NewNode(op, callee, source, function, language, |
2424 eval_scope_position, eval_position); | 2424 eval_scope_position, eval_position); |
2425 PrepareFrameState(new_callee, expr->EvalId(), | 2425 PrepareFrameState(new_callee, expr->EvalId(), |
2426 OutputFrameStateCombine::PokeAt(arg_count + 1)); | 2426 OutputFrameStateCombine::PokeAt(arg_count + 1)); |
2427 | 2427 |
2428 // Patch callee on the environment. | 2428 // Patch callee on the environment. |
2429 environment()->Poke(arg_count + 1, new_callee); | 2429 environment()->Poke(arg_count + 1, new_callee); |
2430 } | 2430 } |
2431 | 2431 |
2432 // Create node to perform the function call. | 2432 // Create node to perform the function call. |
| 2433 float const frequency = ComputeCallFrequency(expr->CallFeedbackICSlot()); |
2433 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); | 2434 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); |
2434 const Operator* call = javascript()->CallFunction( | 2435 const Operator* call = |
2435 args->length() + 2, feedback, receiver_hint, expr->tail_call_mode()); | 2436 javascript()->CallFunction(args->length() + 2, frequency, feedback, |
| 2437 receiver_hint, expr->tail_call_mode()); |
2436 PrepareEagerCheckpoint(possibly_eval ? expr->EvalId() : expr->CallId()); | 2438 PrepareEagerCheckpoint(possibly_eval ? expr->EvalId() : expr->CallId()); |
2437 Node* value = ProcessArguments(call, args->length() + 2); | 2439 Node* value = ProcessArguments(call, args->length() + 2); |
2438 // The callee passed to the call, we just need to push something here to | 2440 // The callee passed to the call, we just need to push something here to |
2439 // satisfy the bailout location contract. The fullcodegen code will not | 2441 // satisfy the bailout location contract. The fullcodegen code will not |
2440 // ever look at this value, so we just push optimized_out here. | 2442 // ever look at this value, so we just push optimized_out here. |
2441 environment()->Push(jsgraph()->OptimizedOutConstant()); | 2443 environment()->Push(jsgraph()->OptimizedOutConstant()); |
2442 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); | 2444 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); |
2443 environment()->Drop(1); | 2445 environment()->Drop(1); |
2444 ast_context()->ProduceValue(expr, value); | 2446 ast_context()->ProduceValue(expr, value); |
2445 } | 2447 } |
(...skipping 13 matching lines...) Expand all Loading... |
2459 | 2461 |
2460 // Evaluate all arguments to the super call. | 2462 // Evaluate all arguments to the super call. |
2461 ZoneList<Expression*>* args = expr->arguments(); | 2463 ZoneList<Expression*>* args = expr->arguments(); |
2462 VisitForValues(args); | 2464 VisitForValues(args); |
2463 | 2465 |
2464 // The new target is loaded from the {new.target} variable. | 2466 // The new target is loaded from the {new.target} variable. |
2465 VisitForValue(super->new_target_var()); | 2467 VisitForValue(super->new_target_var()); |
2466 | 2468 |
2467 // Create node to perform the super call. | 2469 // Create node to perform the super call. |
2468 const Operator* call = | 2470 const Operator* call = |
2469 javascript()->CallConstruct(args->length() + 2, VectorSlotPair()); | 2471 javascript()->CallConstruct(args->length() + 2, 0.0f, VectorSlotPair()); |
2470 Node* value = ProcessArguments(call, args->length() + 2); | 2472 Node* value = ProcessArguments(call, args->length() + 2); |
2471 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); | 2473 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); |
2472 ast_context()->ProduceValue(expr, value); | 2474 ast_context()->ProduceValue(expr, value); |
2473 } | 2475 } |
2474 | 2476 |
2475 | 2477 |
2476 void AstGraphBuilder::VisitCallNew(CallNew* expr) { | 2478 void AstGraphBuilder::VisitCallNew(CallNew* expr) { |
2477 VisitForValue(expr->expression()); | 2479 VisitForValue(expr->expression()); |
2478 | 2480 |
2479 // Evaluate all arguments to the construct call. | 2481 // Evaluate all arguments to the construct call. |
2480 ZoneList<Expression*>* args = expr->arguments(); | 2482 ZoneList<Expression*>* args = expr->arguments(); |
2481 VisitForValues(args); | 2483 VisitForValues(args); |
2482 | 2484 |
2483 // The new target is the same as the callee. | 2485 // The new target is the same as the callee. |
2484 environment()->Push(environment()->Peek(args->length())); | 2486 environment()->Push(environment()->Peek(args->length())); |
2485 | 2487 |
2486 // Create node to perform the construct call. | 2488 // Create node to perform the construct call. |
| 2489 float const frequency = ComputeCallFrequency(expr->CallNewFeedbackSlot()); |
2487 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallNewFeedbackSlot()); | 2490 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallNewFeedbackSlot()); |
2488 const Operator* call = | 2491 const Operator* call = |
2489 javascript()->CallConstruct(args->length() + 2, feedback); | 2492 javascript()->CallConstruct(args->length() + 2, frequency, feedback); |
2490 Node* value = ProcessArguments(call, args->length() + 2); | 2493 Node* value = ProcessArguments(call, args->length() + 2); |
2491 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); | 2494 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); |
2492 ast_context()->ProduceValue(expr, value); | 2495 ast_context()->ProduceValue(expr, value); |
2493 } | 2496 } |
2494 | 2497 |
2495 | 2498 |
2496 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { | 2499 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { |
2497 // The callee and the receiver both have to be pushed onto the operand stack | 2500 // The callee and the receiver both have to be pushed onto the operand stack |
2498 // before arguments are being evaluated. | 2501 // before arguments are being evaluated. |
2499 Node* callee_value = BuildLoadNativeContextField(expr->context_index()); | 2502 Node* callee_value = BuildLoadNativeContextField(expr->context_index()); |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3089 if (!s->NeedsContext()) continue; | 3092 if (!s->NeedsContext()) continue; |
3090 if (!s->calls_sloppy_eval() && s != variable->scope()) continue; | 3093 if (!s->calls_sloppy_eval() && s != variable->scope()) continue; |
3091 int depth = current_scope()->ContextChainLength(s); | 3094 int depth = current_scope()->ContextChainLength(s); |
3092 if (depth > kMaxCheckDepth) return kFullCheckRequired; | 3095 if (depth > kMaxCheckDepth) return kFullCheckRequired; |
3093 check_depths |= 1 << depth; | 3096 check_depths |= 1 << depth; |
3094 if (s == variable->scope()) break; | 3097 if (s == variable->scope()) break; |
3095 } | 3098 } |
3096 return check_depths; | 3099 return check_depths; |
3097 } | 3100 } |
3098 | 3101 |
| 3102 float AstGraphBuilder::ComputeCallFrequency(FeedbackVectorSlot slot) const { |
| 3103 if (slot.IsInvalid()) return 0.0f; |
| 3104 Handle<TypeFeedbackVector> feedback_vector( |
| 3105 info()->closure()->feedback_vector(), isolate()); |
| 3106 CallICNexus nexus(feedback_vector, slot); |
| 3107 return nexus.ExtractCallCount(); |
| 3108 } |
3099 | 3109 |
3100 Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) { | 3110 Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) { |
3101 DCHECK(environment()->stack_height() >= arity); | 3111 DCHECK(environment()->stack_height() >= arity); |
3102 Node** all = info()->zone()->NewArray<Node*>(arity); | 3112 Node** all = info()->zone()->NewArray<Node*>(arity); |
3103 for (int i = arity - 1; i >= 0; --i) { | 3113 for (int i = arity - 1; i >= 0; --i) { |
3104 all[i] = environment()->Pop(); | 3114 all[i] = environment()->Pop(); |
3105 } | 3115 } |
3106 Node* value = NewNode(op, arity, all); | 3116 Node* value = NewNode(op, arity, all); |
3107 return value; | 3117 return value; |
3108 } | 3118 } |
(...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4309 // Phi does not exist yet, introduce one. | 4319 // Phi does not exist yet, introduce one. |
4310 value = NewPhi(inputs, value, control); | 4320 value = NewPhi(inputs, value, control); |
4311 value->ReplaceInput(inputs - 1, other); | 4321 value->ReplaceInput(inputs - 1, other); |
4312 } | 4322 } |
4313 return value; | 4323 return value; |
4314 } | 4324 } |
4315 | 4325 |
4316 } // namespace compiler | 4326 } // namespace compiler |
4317 } // namespace internal | 4327 } // namespace internal |
4318 } // namespace v8 | 4328 } // namespace v8 |
OLD | NEW |