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/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 3435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3446 type_change_checksum_(0), | 3446 type_change_checksum_(0), |
3447 maximum_environment_size_(0), | 3447 maximum_environment_size_(0), |
3448 no_side_effects_scope_count_(0), | 3448 no_side_effects_scope_count_(0), |
3449 disallow_adding_new_values_(false) { | 3449 disallow_adding_new_values_(false) { |
3450 if (info->IsStub()) { | 3450 if (info->IsStub()) { |
3451 CallInterfaceDescriptor descriptor = | 3451 CallInterfaceDescriptor descriptor = |
3452 info->code_stub()->GetCallInterfaceDescriptor(); | 3452 info->code_stub()->GetCallInterfaceDescriptor(); |
3453 start_environment_ = new (zone_) | 3453 start_environment_ = new (zone_) |
3454 HEnvironment(zone_, descriptor.GetEnvironmentParameterCount()); | 3454 HEnvironment(zone_, descriptor.GetEnvironmentParameterCount()); |
3455 } else { | 3455 } else { |
3456 info->TraceInlinedFunction(info->shared_info(), SourcePosition::Unknown()); | 3456 if (FLAG_hydrogen_track_positions) { |
| 3457 info->TraceInlinedFunction(info->shared_info(), |
| 3458 SourcePosition::Unknown()); |
| 3459 } |
3457 start_environment_ = | 3460 start_environment_ = |
3458 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 3461 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
3459 } | 3462 } |
3460 start_environment_->set_ast_id(BailoutId::FunctionEntry()); | 3463 start_environment_->set_ast_id(BailoutId::FunctionEntry()); |
3461 entry_block_ = CreateBasicBlock(); | 3464 entry_block_ = CreateBasicBlock(); |
3462 entry_block_->SetInitialEnvironment(start_environment_); | 3465 entry_block_->SetInitialEnvironment(start_environment_); |
3463 } | 3466 } |
3464 | 3467 |
3465 | 3468 |
3466 HBasicBlock* HGraph::CreateBasicBlock() { | 3469 HBasicBlock* HGraph::CreateBasicBlock() { |
(...skipping 4320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7787 | 7790 |
7788 int nodes_added = target_shared->ast_node_count(); | 7791 int nodes_added = target_shared->ast_node_count(); |
7789 return nodes_added; | 7792 return nodes_added; |
7790 } | 7793 } |
7791 | 7794 |
7792 | 7795 |
7793 bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, | 7796 bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, |
7794 int arguments_count, | 7797 int arguments_count, |
7795 HValue* implicit_return_value, | 7798 HValue* implicit_return_value, |
7796 BailoutId ast_id, BailoutId return_id, | 7799 BailoutId ast_id, BailoutId return_id, |
7797 InliningKind inlining_kind, | 7800 InliningKind inlining_kind) { |
7798 SourcePosition position) { | |
7799 int nodes_added = InliningAstSize(target); | 7801 int nodes_added = InliningAstSize(target); |
7800 if (nodes_added == kNotInlinable) return false; | 7802 if (nodes_added == kNotInlinable) return false; |
7801 | 7803 |
7802 Handle<JSFunction> caller = current_info()->closure(); | 7804 Handle<JSFunction> caller = current_info()->closure(); |
7803 | 7805 |
7804 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { | 7806 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { |
7805 TraceInline(target, caller, "target AST is too large [early]"); | 7807 TraceInline(target, caller, "target AST is too large [early]"); |
7806 return false; | 7808 return false; |
7807 } | 7809 } |
7808 | 7810 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7900 } | 7902 } |
7901 | 7903 |
7902 // ---------------------------------------------------------------- | 7904 // ---------------------------------------------------------------- |
7903 // After this point, we've made a decision to inline this function (so | 7905 // After this point, we've made a decision to inline this function (so |
7904 // TryInline should always return true). | 7906 // TryInline should always return true). |
7905 | 7907 |
7906 // Type-check the inlined function. | 7908 // Type-check the inlined function. |
7907 DCHECK(target_shared->has_deoptimization_support()); | 7909 DCHECK(target_shared->has_deoptimization_support()); |
7908 AstTyper::Run(&target_info); | 7910 AstTyper::Run(&target_info); |
7909 | 7911 |
7910 int function_id = top_info()->TraceInlinedFunction(target_shared, position); | 7912 int function_id = 0; |
| 7913 if (FLAG_hydrogen_track_positions) { |
| 7914 function_id = |
| 7915 top_info()->TraceInlinedFunction(target_shared, source_position()); |
| 7916 } |
7911 | 7917 |
7912 // Save the pending call context. Set up new one for the inlined function. | 7918 // Save the pending call context. Set up new one for the inlined function. |
7913 // The function state is new-allocated because we need to delete it | 7919 // The function state is new-allocated because we need to delete it |
7914 // in two different places. | 7920 // in two different places. |
7915 FunctionState* target_state = new FunctionState( | 7921 FunctionState* target_state = new FunctionState( |
7916 this, &target_info, inlining_kind, function_id); | 7922 this, &target_info, inlining_kind, function_id); |
7917 | 7923 |
7918 HConstant* undefined = graph()->GetConstantUndefined(); | 7924 HConstant* undefined = graph()->GetConstantUndefined(); |
7919 | 7925 |
7920 HEnvironment* inner_env = | 7926 HEnvironment* inner_env = |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8056 set_current_block(function_return()); | 8062 set_current_block(function_return()); |
8057 } else { | 8063 } else { |
8058 set_current_block(NULL); | 8064 set_current_block(NULL); |
8059 } | 8065 } |
8060 delete target_state; | 8066 delete target_state; |
8061 return true; | 8067 return true; |
8062 } | 8068 } |
8063 | 8069 |
8064 | 8070 |
8065 bool HOptimizedGraphBuilder::TryInlineCall(Call* expr) { | 8071 bool HOptimizedGraphBuilder::TryInlineCall(Call* expr) { |
8066 return TryInline(expr->target(), | 8072 return TryInline(expr->target(), expr->arguments()->length(), NULL, |
8067 expr->arguments()->length(), | 8073 expr->id(), expr->ReturnId(), NORMAL_RETURN); |
8068 NULL, | |
8069 expr->id(), | |
8070 expr->ReturnId(), | |
8071 NORMAL_RETURN, | |
8072 ScriptPositionToSourcePosition(expr->position())); | |
8073 } | 8074 } |
8074 | 8075 |
8075 | 8076 |
8076 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, | 8077 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, |
8077 HValue* implicit_return_value) { | 8078 HValue* implicit_return_value) { |
8078 return TryInline(expr->target(), | 8079 return TryInline(expr->target(), expr->arguments()->length(), |
8079 expr->arguments()->length(), | 8080 implicit_return_value, expr->id(), expr->ReturnId(), |
8080 implicit_return_value, | 8081 CONSTRUCT_CALL_RETURN); |
8081 expr->id(), | |
8082 expr->ReturnId(), | |
8083 CONSTRUCT_CALL_RETURN, | |
8084 ScriptPositionToSourcePosition(expr->position())); | |
8085 } | 8082 } |
8086 | 8083 |
8087 | 8084 |
8088 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, | 8085 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, |
8089 Handle<Map> receiver_map, | 8086 Handle<Map> receiver_map, |
8090 BailoutId ast_id, | 8087 BailoutId ast_id, |
8091 BailoutId return_id) { | 8088 BailoutId return_id) { |
8092 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; | 8089 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; |
8093 return TryInline(getter, | 8090 return TryInline(getter, 0, NULL, ast_id, return_id, GETTER_CALL_RETURN); |
8094 0, | |
8095 NULL, | |
8096 ast_id, | |
8097 return_id, | |
8098 GETTER_CALL_RETURN, | |
8099 source_position()); | |
8100 } | 8091 } |
8101 | 8092 |
8102 | 8093 |
8103 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, | 8094 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, |
8104 Handle<Map> receiver_map, | 8095 Handle<Map> receiver_map, |
8105 BailoutId id, | 8096 BailoutId id, |
8106 BailoutId assignment_id, | 8097 BailoutId assignment_id, |
8107 HValue* implicit_return_value) { | 8098 HValue* implicit_return_value) { |
8108 if (TryInlineApiSetter(setter, receiver_map, id)) return true; | 8099 if (TryInlineApiSetter(setter, receiver_map, id)) return true; |
8109 return TryInline(setter, | 8100 return TryInline(setter, 1, implicit_return_value, id, assignment_id, |
8110 1, | 8101 SETTER_CALL_RETURN); |
8111 implicit_return_value, | |
8112 id, assignment_id, | |
8113 SETTER_CALL_RETURN, | |
8114 source_position()); | |
8115 } | 8102 } |
8116 | 8103 |
8117 | 8104 |
8118 bool HOptimizedGraphBuilder::TryInlineIndirectCall(Handle<JSFunction> function, | 8105 bool HOptimizedGraphBuilder::TryInlineIndirectCall(Handle<JSFunction> function, |
8119 Call* expr, | 8106 Call* expr, |
8120 int arguments_count) { | 8107 int arguments_count) { |
8121 return TryInline(function, | 8108 return TryInline(function, arguments_count, NULL, expr->id(), |
8122 arguments_count, | 8109 expr->ReturnId(), NORMAL_RETURN); |
8123 NULL, | |
8124 expr->id(), | |
8125 expr->ReturnId(), | |
8126 NORMAL_RETURN, | |
8127 ScriptPositionToSourcePosition(expr->position())); | |
8128 } | 8110 } |
8129 | 8111 |
8130 | 8112 |
8131 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr) { | 8113 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr) { |
8132 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; | 8114 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; |
8133 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | 8115 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
8134 switch (id) { | 8116 switch (id) { |
8135 case kMathExp: | 8117 case kMathExp: |
8136 if (!FLAG_fast_math) break; | 8118 if (!FLAG_fast_math) break; |
8137 // Fall through if FLAG_fast_math. | 8119 // Fall through if FLAG_fast_math. |
(...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9145 | 9127 |
9146 HValue* key = NULL; | 9128 HValue* key = NULL; |
9147 if (!prop->key()->IsPropertyName()) { | 9129 if (!prop->key()->IsPropertyName()) { |
9148 CHECK_ALIVE(VisitForValue(prop->key())); | 9130 CHECK_ALIVE(VisitForValue(prop->key())); |
9149 key = Pop(); | 9131 key = Pop(); |
9150 } | 9132 } |
9151 | 9133 |
9152 CHECK_ALIVE(PushLoad(prop, receiver, key)); | 9134 CHECK_ALIVE(PushLoad(prop, receiver, key)); |
9153 HValue* function = Pop(); | 9135 HValue* function = Pop(); |
9154 | 9136 |
9155 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); | |
9156 | |
9157 if (function->IsConstant() && | 9137 if (function->IsConstant() && |
9158 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | 9138 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
9159 // Push the function under the receiver. | 9139 // Push the function under the receiver. |
9160 environment()->SetExpressionStackAt(0, function); | 9140 environment()->SetExpressionStackAt(0, function); |
9161 Push(receiver); | 9141 Push(receiver); |
9162 | 9142 |
9163 Handle<JSFunction> known_function = Handle<JSFunction>::cast( | 9143 Handle<JSFunction> known_function = Handle<JSFunction>::cast( |
9164 HConstant::cast(function)->handle(isolate())); | 9144 HConstant::cast(function)->handle(isolate())); |
9165 expr->set_target(known_function); | 9145 expr->set_target(known_function); |
9166 | 9146 |
(...skipping 1687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10854 return ast_context()->ReturnControl(instr, expr->id()); | 10834 return ast_context()->ReturnControl(instr, expr->id()); |
10855 } | 10835 } |
10856 | 10836 |
10857 Type* left_type = expr->left()->bounds().lower; | 10837 Type* left_type = expr->left()->bounds().lower; |
10858 Type* right_type = expr->right()->bounds().lower; | 10838 Type* right_type = expr->right()->bounds().lower; |
10859 Type* combined_type = expr->combined_type(); | 10839 Type* combined_type = expr->combined_type(); |
10860 | 10840 |
10861 CHECK_ALIVE(VisitForValue(expr->left())); | 10841 CHECK_ALIVE(VisitForValue(expr->left())); |
10862 CHECK_ALIVE(VisitForValue(expr->right())); | 10842 CHECK_ALIVE(VisitForValue(expr->right())); |
10863 | 10843 |
10864 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); | |
10865 | |
10866 HValue* right = Pop(); | 10844 HValue* right = Pop(); |
10867 HValue* left = Pop(); | 10845 HValue* left = Pop(); |
10868 Token::Value op = expr->op(); | 10846 Token::Value op = expr->op(); |
10869 | 10847 |
10870 if (IsLiteralCompareBool(isolate(), left, op, right)) { | 10848 if (IsLiteralCompareBool(isolate(), left, op, right)) { |
10871 HCompareObjectEqAndBranch* result = | 10849 HCompareObjectEqAndBranch* result = |
10872 New<HCompareObjectEqAndBranch>(left, right); | 10850 New<HCompareObjectEqAndBranch>(left, right); |
10873 return ast_context()->ReturnControl(result, expr->id()); | 10851 return ast_context()->ReturnControl(result, expr->id()); |
10874 } | 10852 } |
10875 | 10853 |
(...skipping 2563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13439 if (ShouldProduceTraceOutput()) { | 13417 if (ShouldProduceTraceOutput()) { |
13440 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13418 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13441 } | 13419 } |
13442 | 13420 |
13443 #ifdef DEBUG | 13421 #ifdef DEBUG |
13444 graph_->Verify(false); // No full verify. | 13422 graph_->Verify(false); // No full verify. |
13445 #endif | 13423 #endif |
13446 } | 13424 } |
13447 | 13425 |
13448 } } // namespace v8::internal | 13426 } } // namespace v8::internal |
OLD | NEW |