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

Side by Side Diff: src/hydrogen.cc

Issue 7033020: When inlining fails, disable optimization of the proper function. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 7 months 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 | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/objects.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 514
515 HConstant* HGraph::GetConstantTrue() { 515 HConstant* HGraph::GetConstantTrue() {
516 return GetConstant(&constant_true_, isolate()->heap()->true_value()); 516 return GetConstant(&constant_true_, isolate()->heap()->true_value());
517 } 517 }
518 518
519 519
520 HConstant* HGraph::GetConstantFalse() { 520 HConstant* HGraph::GetConstantFalse() {
521 return GetConstant(&constant_false_, isolate()->heap()->false_value()); 521 return GetConstant(&constant_false_, isolate()->heap()->false_value());
522 } 522 }
523 523
524 HGraphBuilder::HGraphBuilder(CompilationInfo* info,
525 TypeFeedbackOracle* oracle)
526 : function_state_(NULL),
527 initial_function_state_(this, info, oracle),
528 ast_context_(NULL),
529 break_scope_(NULL),
530 graph_(NULL),
531 current_block_(NULL),
532 inlined_count_(0),
533 zone_(info->isolate()->zone()),
534 inline_bailout_(false) {
535 // This is not initialized in the initializer list because the
536 // constructor for the initial state relies on function_state_ == NULL
537 // to know it's the initial state.
538 function_state_= &initial_function_state_;
539 }
524 540
525 HBasicBlock* HGraphBuilder::CreateJoin(HBasicBlock* first, 541 HBasicBlock* HGraphBuilder::CreateJoin(HBasicBlock* first,
526 HBasicBlock* second, 542 HBasicBlock* second,
527 int join_id) { 543 int join_id) {
528 if (first == NULL) { 544 if (first == NULL) {
529 return second; 545 return second;
530 } else if (second == NULL) { 546 } else if (second == NULL) {
531 return first; 547 return first;
532 } else { 548 } else {
533 HBasicBlock* join_block = graph_->CreateBasicBlock(); 549 HBasicBlock* join_block = graph_->CreateBasicBlock();
(...skipping 3505 matching lines...) Expand 10 before | Expand all | Expand 10 after
4039 } 4055 }
4040 } 4056 }
4041 4057
4042 4058
4043 bool HGraphBuilder::TryInline(Call* expr) { 4059 bool HGraphBuilder::TryInline(Call* expr) {
4044 if (!FLAG_use_inlining) return false; 4060 if (!FLAG_use_inlining) return false;
4045 4061
4046 // Precondition: call is monomorphic and we have found a target with the 4062 // Precondition: call is monomorphic and we have found a target with the
4047 // appropriate arity. 4063 // appropriate arity.
4048 Handle<JSFunction> target = expr->target(); 4064 Handle<JSFunction> target = expr->target();
4065 Handle<SharedFunctionInfo> target_shared(target->shared());
4049 4066
4050 // Do a quick check on source code length to avoid parsing large 4067 // Do a quick check on source code length to avoid parsing large
4051 // inlining candidates. 4068 // inlining candidates.
4052 if (FLAG_limit_inlining && target->shared()->SourceSize() > kMaxSourceSize) { 4069 if (FLAG_limit_inlining && target_shared->SourceSize() > kMaxSourceSize) {
4053 TraceInline(target, "target text too big"); 4070 TraceInline(target, "target text too big");
4054 return false; 4071 return false;
4055 } 4072 }
4056 4073
4057 // Target must be inlineable. 4074 // Target must be inlineable.
4058 if (!target->IsInlineable()) { 4075 if (!target->IsInlineable()) {
4059 TraceInline(target, "target not inlineable"); 4076 TraceInline(target, "target not inlineable");
4060 return false; 4077 return false;
4061 } 4078 }
4062 4079
(...skipping 12 matching lines...) Expand all
4075 while (env->outer() != NULL) { 4092 while (env->outer() != NULL) {
4076 if (current_level == Compiler::kMaxInliningLevels) { 4093 if (current_level == Compiler::kMaxInliningLevels) {
4077 TraceInline(target, "inline depth limit reached"); 4094 TraceInline(target, "inline depth limit reached");
4078 return false; 4095 return false;
4079 } 4096 }
4080 current_level++; 4097 current_level++;
4081 env = env->outer(); 4098 env = env->outer();
4082 } 4099 }
4083 4100
4084 // Don't inline recursive functions. 4101 // Don't inline recursive functions.
4085 if (target->shared() == outer_info->closure()->shared()) { 4102 if (*target_shared == outer_info->closure()->shared()) {
4086 TraceInline(target, "target is recursive"); 4103 TraceInline(target, "target is recursive");
4087 return false; 4104 return false;
4088 } 4105 }
4089 4106
4090 // We don't want to add more than a certain number of nodes from inlining. 4107 // We don't want to add more than a certain number of nodes from inlining.
4091 if (FLAG_limit_inlining && inlined_count_ > kMaxInlinedNodes) { 4108 if (FLAG_limit_inlining && inlined_count_ > kMaxInlinedNodes) {
4092 TraceInline(target, "cumulative AST node limit reached"); 4109 TraceInline(target, "cumulative AST node limit reached");
4093 return false; 4110 return false;
4094 } 4111 }
4095 4112
4096 int count_before = AstNode::Count(); 4113 int count_before = AstNode::Count();
4097 4114
4098 // Parse and allocate variables. 4115 // Parse and allocate variables.
4099 CompilationInfo target_info(target); 4116 CompilationInfo target_info(target);
4100 if (!ParserApi::Parse(&target_info) || 4117 if (!ParserApi::Parse(&target_info) ||
4101 !Scope::Analyze(&target_info)) { 4118 !Scope::Analyze(&target_info)) {
4102 if (target_info.isolate()->has_pending_exception()) { 4119 if (target_info.isolate()->has_pending_exception()) {
4103 // Parse or scope error, never optimize this function. 4120 // Parse or scope error, never optimize this function.
4104 SetStackOverflow(); 4121 SetStackOverflow();
4105 target->shared()->set_optimization_disabled(true); 4122 target_shared->DisableOptimization(*target);
4106 } 4123 }
4107 TraceInline(target, "parse failure"); 4124 TraceInline(target, "parse failure");
4108 return false; 4125 return false;
4109 } 4126 }
4110 4127
4111 if (target_info.scope()->num_heap_slots() > 0) { 4128 if (target_info.scope()->num_heap_slots() > 0) {
4112 TraceInline(target, "target has context-allocated variables"); 4129 TraceInline(target, "target has context-allocated variables");
4113 return false; 4130 return false;
4114 } 4131 }
4115 FunctionLiteral* function = target_info.function(); 4132 FunctionLiteral* function = target_info.function();
4116 4133
4117 // Count the number of AST nodes added by inlining this call. 4134 // Count the number of AST nodes added by inlining this call.
4118 int nodes_added = AstNode::Count() - count_before; 4135 int nodes_added = AstNode::Count() - count_before;
4119 if (FLAG_limit_inlining && nodes_added > kMaxInlinedSize) { 4136 if (FLAG_limit_inlining && nodes_added > kMaxInlinedSize) {
4120 TraceInline(target, "target AST is too large"); 4137 TraceInline(target, "target AST is too large");
4121 return false; 4138 return false;
4122 } 4139 }
4123 4140
4124 // Check if we can handle all declarations in the inlined functions. 4141 // Check if we can handle all declarations in the inlined functions.
4125 VisitDeclarations(target_info.scope()->declarations()); 4142 VisitDeclarations(target_info.scope()->declarations());
4126 if (HasStackOverflow()) { 4143 if (HasStackOverflow()) {
4127 TraceInline(target, "target has non-trivial declaration"); 4144 TraceInline(target, "target has non-trivial declaration");
4128 ClearStackOverflow(); 4145 ClearStackOverflow();
4129 return false; 4146 return false;
4130 } 4147 }
4131 4148
4132 // Don't inline functions that uses the arguments object or that 4149 // Don't inline functions that uses the arguments object or that
4133 // have a mismatching number of parameters. 4150 // have a mismatching number of parameters.
4134 Handle<SharedFunctionInfo> target_shared(target->shared());
4135 int arity = expr->arguments()->length(); 4151 int arity = expr->arguments()->length();
4136 if (function->scope()->arguments() != NULL || 4152 if (function->scope()->arguments() != NULL ||
4137 arity != target_shared->formal_parameter_count()) { 4153 arity != target_shared->formal_parameter_count()) {
4138 TraceInline(target, "target requires special argument handling"); 4154 TraceInline(target, "target requires special argument handling");
4139 return false; 4155 return false;
4140 } 4156 }
4141 4157
4142 // All statements in the body must be inlineable. 4158 // All statements in the body must be inlineable.
4143 for (int i = 0, count = function->body()->length(); i < count; ++i) { 4159 for (int i = 0, count = function->body()->length(); i < count; ++i) {
4144 if (!function->body()->at(i)->IsInlineable()) { 4160 if (!function->body()->at(i)->IsInlineable()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4182 current_block()->Goto(body_entry); 4198 current_block()->Goto(body_entry);
4183 4199
4184 body_entry->SetJoinId(expr->ReturnId()); 4200 body_entry->SetJoinId(expr->ReturnId());
4185 set_current_block(body_entry); 4201 set_current_block(body_entry);
4186 AddInstruction(new(zone()) HEnterInlined(target, function)); 4202 AddInstruction(new(zone()) HEnterInlined(target, function));
4187 VisitStatements(function->body()); 4203 VisitStatements(function->body());
4188 if (HasStackOverflow()) { 4204 if (HasStackOverflow()) {
4189 // Bail out if the inline function did, as we cannot residualize a call 4205 // Bail out if the inline function did, as we cannot residualize a call
4190 // instead. 4206 // instead.
4191 TraceInline(target, "inline graph construction failed"); 4207 TraceInline(target, "inline graph construction failed");
4208 target_shared->DisableOptimization(*target);
4209 inline_bailout_ = true;
4192 return true; 4210 return true;
4193 } 4211 }
4194 4212
4195 // Update inlined nodes count. 4213 // Update inlined nodes count.
4196 inlined_count_ += nodes_added; 4214 inlined_count_ += nodes_added;
4197 4215
4198 TraceInline(target, NULL); 4216 TraceInline(target, NULL);
4199 4217
4200 if (current_block() != NULL) { 4218 if (current_block() != NULL) {
4201 // Add a return of undefined if control can fall off the body. In a 4219 // Add a return of undefined if control can fall off the body. In a
(...skipping 1998 matching lines...) Expand 10 before | Expand all | Expand 10 after
6200 } 6218 }
6201 } 6219 }
6202 6220
6203 #ifdef DEBUG 6221 #ifdef DEBUG
6204 if (graph_ != NULL) graph_->Verify(); 6222 if (graph_ != NULL) graph_->Verify();
6205 if (allocator_ != NULL) allocator_->Verify(); 6223 if (allocator_ != NULL) allocator_->Verify();
6206 #endif 6224 #endif
6207 } 6225 }
6208 6226
6209 } } // namespace v8::internal 6227 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698