OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
(...skipping 7977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7988 } | 7988 } |
7989 } | 7989 } |
7990 | 7990 |
7991 HInstruction* HOptimizedGraphBuilder::NewCallFunction( | 7991 HInstruction* HOptimizedGraphBuilder::NewCallFunction( |
7992 HValue* function, int argument_count, ConvertReceiverMode convert_mode, | 7992 HValue* function, int argument_count, ConvertReceiverMode convert_mode, |
7993 TailCallMode tail_call_mode) { | 7993 TailCallMode tail_call_mode) { |
7994 HValue* arity = Add<HConstant>(argument_count - 1); | 7994 HValue* arity = Add<HConstant>(argument_count - 1); |
7995 | 7995 |
7996 HValue* op_vals[] = {context(), function, arity}; | 7996 HValue* op_vals[] = {context(), function, arity}; |
7997 | 7997 |
7998 // TODO(ishell): use tail_call_mode here. | 7998 Callable callable = |
7999 Callable callable = CodeFactory::Call(isolate(), convert_mode); | 7999 CodeFactory::Call(isolate(), convert_mode, tail_call_mode); |
8000 HConstant* stub = Add<HConstant>(callable.code()); | 8000 HConstant* stub = Add<HConstant>(callable.code()); |
8001 | 8001 |
8002 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), | 8002 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), |
8003 Vector<HValue*>(op_vals, arraysize(op_vals))); | 8003 Vector<HValue*>(op_vals, arraysize(op_vals))); |
8004 } | 8004 } |
8005 | 8005 |
8006 HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC( | 8006 HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC( |
8007 HValue* function, int argument_count, ConvertReceiverMode convert_mode, | 8007 HValue* function, int argument_count, ConvertReceiverMode convert_mode, |
8008 TailCallMode tail_call_mode, FeedbackVectorSlot slot) { | 8008 TailCallMode tail_call_mode, FeedbackVectorSlot slot) { |
8009 int arity = argument_count - 1; | 8009 int arity = argument_count - 1; |
8010 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate()); | 8010 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate()); |
8011 HValue* index_val = Add<HConstant>(vector->GetIndex(slot)); | 8011 HValue* index_val = Add<HConstant>(vector->GetIndex(slot)); |
8012 HValue* vector_val = Add<HConstant>(vector); | 8012 HValue* vector_val = Add<HConstant>(vector); |
8013 | 8013 |
8014 HValue* op_vals[] = {context(), function, index_val, vector_val}; | 8014 HValue* op_vals[] = {context(), function, index_val, vector_val}; |
8015 | 8015 |
8016 // TODO(ishell): use tail_call_mode here. | |
8017 Callable callable = CodeFactory::CallICInOptimizedCode( | 8016 Callable callable = CodeFactory::CallICInOptimizedCode( |
8018 isolate(), arity, ConvertReceiverMode::kNullOrUndefined); | 8017 isolate(), arity, ConvertReceiverMode::kNullOrUndefined, tail_call_mode); |
8019 HConstant* stub = Add<HConstant>(callable.code()); | 8018 HConstant* stub = Add<HConstant>(callable.code()); |
8020 | 8019 |
8021 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), | 8020 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), |
8022 Vector<HValue*>(op_vals, arraysize(op_vals))); | 8021 Vector<HValue*>(op_vals, arraysize(op_vals))); |
8023 } | 8022 } |
8024 | 8023 |
8025 HInstruction* HOptimizedGraphBuilder::NewCallConstantFunction( | 8024 HInstruction* HOptimizedGraphBuilder::NewCallConstantFunction( |
8026 Handle<JSFunction> function, int argument_count, | 8025 Handle<JSFunction> function, int argument_count, |
8027 TailCallMode tail_call_mode) { | 8026 TailCallMode tail_call_mode) { |
8028 // TODO(ishell): use tail_call_mode here. | |
8029 HValue* target = Add<HConstant>(function); | 8027 HValue* target = Add<HConstant>(function); |
8030 return New<HInvokeFunction>(target, function, argument_count); | 8028 return New<HInvokeFunction>(target, function, argument_count, tail_call_mode); |
8031 } | 8029 } |
8032 | 8030 |
8033 | 8031 |
8034 class FunctionSorter { | 8032 class FunctionSorter { |
8035 public: | 8033 public: |
8036 explicit FunctionSorter(int index = 0, int ticks = 0, int size = 0) | 8034 explicit FunctionSorter(int index = 0, int ticks = 0, int size = 0) |
8037 : index_(index), ticks_(ticks), size_(size) {} | 8035 : index_(index), ticks_(ticks), size_(size) {} |
8038 | 8036 |
8039 int index() const { return index_; } | 8037 int index() const { return index_; } |
8040 int ticks() const { return ticks_; } | 8038 int ticks() const { return ticks_; } |
(...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9370 } | 9368 } |
9371 | 9369 |
9372 if (TryInlineIndirectCall(known_function, expr, args_count_no_receiver)) { | 9370 if (TryInlineIndirectCall(known_function, expr, args_count_no_receiver)) { |
9373 return; | 9371 return; |
9374 } | 9372 } |
9375 } | 9373 } |
9376 | 9374 |
9377 TailCallMode syntactic_tail_call_mode = expr->tail_call_mode(); | 9375 TailCallMode syntactic_tail_call_mode = expr->tail_call_mode(); |
9378 TailCallMode tail_call_mode = | 9376 TailCallMode tail_call_mode = |
9379 function_state()->ComputeTailCallMode(syntactic_tail_call_mode); | 9377 function_state()->ComputeTailCallMode(syntactic_tail_call_mode); |
9380 USE(tail_call_mode); | |
9381 | 9378 |
9382 // TODO(ishell): use tail_call_mode here. | |
9383 PushArgumentsFromEnvironment(arguments_count); | 9379 PushArgumentsFromEnvironment(arguments_count); |
9384 HInvokeFunction* call = | 9380 HInvokeFunction* call = New<HInvokeFunction>(function, known_function, |
9385 New<HInvokeFunction>(function, known_function, arguments_count); | 9381 arguments_count, tail_call_mode); |
9386 Drop(1); // Function | 9382 Drop(1); // Function |
9387 ast_context()->ReturnInstruction(call, expr->id()); | 9383 ast_context()->ReturnInstruction(call, expr->id()); |
9388 } | 9384 } |
9389 | 9385 |
9390 | 9386 |
9391 bool HOptimizedGraphBuilder::TryIndirectCall(Call* expr) { | 9387 bool HOptimizedGraphBuilder::TryIndirectCall(Call* expr) { |
9392 DCHECK(expr->expression()->IsProperty()); | 9388 DCHECK(expr->expression()->IsProperty()); |
9393 | 9389 |
9394 if (!expr->IsMonomorphic()) { | 9390 if (!expr->IsMonomorphic()) { |
9395 return false; | 9391 return false; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9430 HValue* function = Pop(); // f | 9426 HValue* function = Pop(); // f |
9431 Drop(1); // apply | 9427 Drop(1); // apply |
9432 | 9428 |
9433 Handle<Map> function_map = expr->GetReceiverTypes()->first(); | 9429 Handle<Map> function_map = expr->GetReceiverTypes()->first(); |
9434 HValue* checked_function = AddCheckMap(function, function_map); | 9430 HValue* checked_function = AddCheckMap(function, function_map); |
9435 | 9431 |
9436 if (function_state()->outer() == NULL) { | 9432 if (function_state()->outer() == NULL) { |
9437 TailCallMode syntactic_tail_call_mode = expr->tail_call_mode(); | 9433 TailCallMode syntactic_tail_call_mode = expr->tail_call_mode(); |
9438 TailCallMode tail_call_mode = | 9434 TailCallMode tail_call_mode = |
9439 function_state()->ComputeTailCallMode(syntactic_tail_call_mode); | 9435 function_state()->ComputeTailCallMode(syntactic_tail_call_mode); |
9440 USE(tail_call_mode); | |
9441 | 9436 |
9442 // TODO(ishell): use tail_call_mode here. | |
9443 HInstruction* elements = Add<HArgumentsElements>(false); | 9437 HInstruction* elements = Add<HArgumentsElements>(false); |
9444 HInstruction* length = Add<HArgumentsLength>(elements); | 9438 HInstruction* length = Add<HArgumentsLength>(elements); |
9445 HValue* wrapped_receiver = BuildWrapReceiver(receiver, checked_function); | 9439 HValue* wrapped_receiver = BuildWrapReceiver(receiver, checked_function); |
9446 HInstruction* result = New<HApplyArguments>(function, | 9440 HInstruction* result = New<HApplyArguments>( |
9447 wrapped_receiver, | 9441 function, wrapped_receiver, length, elements, tail_call_mode); |
9448 length, | |
9449 elements); | |
9450 ast_context()->ReturnInstruction(result, expr->id()); | 9442 ast_context()->ReturnInstruction(result, expr->id()); |
9451 } else { | 9443 } else { |
9452 // We are inside inlined function and we know exactly what is inside | 9444 // We are inside inlined function and we know exactly what is inside |
9453 // arguments object. But we need to be able to materialize at deopt. | 9445 // arguments object. But we need to be able to materialize at deopt. |
9454 DCHECK_EQ(environment()->arguments_environment()->parameter_count(), | 9446 DCHECK_EQ(environment()->arguments_environment()->parameter_count(), |
9455 function_state()->entry()->arguments_object()->arguments_count()); | 9447 function_state()->entry()->arguments_object()->arguments_count()); |
9456 HArgumentsObject* args = function_state()->entry()->arguments_object(); | 9448 HArgumentsObject* args = function_state()->entry()->arguments_object(); |
9457 const ZoneList<HValue*>* arguments_values = args->arguments_values(); | 9449 const ZoneList<HValue*>* arguments_values = args->arguments_values(); |
9458 int arguments_count = arguments_values->length(); | 9450 int arguments_count = arguments_values->length(); |
9459 Push(function); | 9451 Push(function); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9707 if (args->length() != 2) return false; | 9699 if (args->length() != 2) return false; |
9708 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); | 9700 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); |
9709 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; | 9701 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; |
9710 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); | 9702 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); |
9711 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; | 9703 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; |
9712 return true; | 9704 return true; |
9713 } | 9705 } |
9714 | 9706 |
9715 | 9707 |
9716 void HOptimizedGraphBuilder::VisitCall(Call* expr) { | 9708 void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
9717 if (expr->tail_call_mode() == TailCallMode::kAllow) { | |
9718 return Bailout(kTailCall); | |
9719 } | |
9720 DCHECK(!HasStackOverflow()); | 9709 DCHECK(!HasStackOverflow()); |
9721 DCHECK(current_block() != NULL); | 9710 DCHECK(current_block() != NULL); |
9722 DCHECK(current_block()->HasPredecessor()); | 9711 DCHECK(current_block()->HasPredecessor()); |
9723 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); | 9712 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); |
9724 Expression* callee = expr->expression(); | 9713 Expression* callee = expr->expression(); |
9725 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 9714 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
9726 HInstruction* call = NULL; | 9715 HInstruction* call = NULL; |
9727 | 9716 |
9728 TailCallMode syntactic_tail_call_mode = expr->tail_call_mode(); | 9717 TailCallMode syntactic_tail_call_mode = expr->tail_call_mode(); |
9729 TailCallMode tail_call_mode = | 9718 TailCallMode tail_call_mode = |
(...skipping 3776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13506 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13495 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13507 } | 13496 } |
13508 | 13497 |
13509 #ifdef DEBUG | 13498 #ifdef DEBUG |
13510 graph_->Verify(false); // No full verify. | 13499 graph_->Verify(false); // No full verify. |
13511 #endif | 13500 #endif |
13512 } | 13501 } |
13513 | 13502 |
13514 } // namespace internal | 13503 } // namespace internal |
13515 } // namespace v8 | 13504 } // namespace v8 |
OLD | NEW |