| 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 |