OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 5337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5348 ReturnHandlingFlag return_handling) { | 5348 ReturnHandlingFlag return_handling) { |
5349 if (!FLAG_use_inlining) return false; | 5349 if (!FLAG_use_inlining) return false; |
5350 | 5350 |
5351 // Precondition: call is monomorphic and we have found a target with the | 5351 // Precondition: call is monomorphic and we have found a target with the |
5352 // appropriate arity. | 5352 // appropriate arity. |
5353 Handle<JSFunction> caller = info()->closure(); | 5353 Handle<JSFunction> caller = info()->closure(); |
5354 Handle<SharedFunctionInfo> target_shared(target->shared()); | 5354 Handle<SharedFunctionInfo> target_shared(target->shared()); |
5355 | 5355 |
5356 // Do a quick check on source code length to avoid parsing large | 5356 // Do a quick check on source code length to avoid parsing large |
5357 // inlining candidates. | 5357 // inlining candidates. |
5358 if ((FLAG_limit_inlining && target_shared->SourceSize() > kMaxSourceSize) | 5358 if (target_shared->SourceSize() > |
5359 || target_shared->SourceSize() > kUnlimitedMaxSourceSize) { | 5359 Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) { |
5360 TraceInline(target, caller, "target text too big"); | 5360 TraceInline(target, caller, "target text too big"); |
5361 return false; | 5361 return false; |
5362 } | 5362 } |
5363 | 5363 |
5364 // Target must be inlineable. | 5364 // Target must be inlineable. |
5365 if (!target->IsInlineable()) { | 5365 if (!target->IsInlineable()) { |
5366 TraceInline(target, caller, "target not inlineable"); | 5366 TraceInline(target, caller, "target not inlineable"); |
5367 return false; | 5367 return false; |
5368 } | 5368 } |
5369 if (target_shared->dont_inline() || target_shared->dont_optimize()) { | 5369 if (target_shared->dont_inline() || target_shared->dont_optimize()) { |
5370 TraceInline(target, caller, "target contains unsupported syntax [early]"); | 5370 TraceInline(target, caller, "target contains unsupported syntax [early]"); |
5371 return false; | 5371 return false; |
5372 } | 5372 } |
5373 | 5373 |
5374 int nodes_added = target_shared->ast_node_count(); | 5374 int nodes_added = target_shared->ast_node_count(); |
5375 if ((FLAG_limit_inlining && nodes_added > kMaxInlinedSize) || | 5375 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { |
5376 nodes_added > kUnlimitedMaxInlinedSize) { | |
5377 TraceInline(target, caller, "target AST is too large [early]"); | 5376 TraceInline(target, caller, "target AST is too large [early]"); |
5378 return false; | 5377 return false; |
5379 } | 5378 } |
5380 | 5379 |
5381 #if !defined(V8_TARGET_ARCH_IA32) | 5380 #if !defined(V8_TARGET_ARCH_IA32) |
5382 // Target must be able to use caller's context. | 5381 // Target must be able to use caller's context. |
5383 CompilationInfo* outer_info = info(); | 5382 CompilationInfo* outer_info = info(); |
5384 if (target->context() != outer_info->closure()->context() || | 5383 if (target->context() != outer_info->closure()->context() || |
5385 outer_info->scope()->contains_with() || | 5384 outer_info->scope()->contains_with() || |
5386 outer_info->scope()->num_heap_slots() > 0) { | 5385 outer_info->scope()->num_heap_slots() > 0) { |
(...skipping 21 matching lines...) Expand all Loading... |
5408 for (FunctionState* state = function_state(); | 5407 for (FunctionState* state = function_state(); |
5409 state != NULL; | 5408 state != NULL; |
5410 state = state->outer()) { | 5409 state = state->outer()) { |
5411 if (state->compilation_info()->closure()->shared() == *target_shared) { | 5410 if (state->compilation_info()->closure()->shared() == *target_shared) { |
5412 TraceInline(target, caller, "target is recursive"); | 5411 TraceInline(target, caller, "target is recursive"); |
5413 return false; | 5412 return false; |
5414 } | 5413 } |
5415 } | 5414 } |
5416 | 5415 |
5417 // We don't want to add more than a certain number of nodes from inlining. | 5416 // We don't want to add more than a certain number of nodes from inlining. |
5418 if ((FLAG_limit_inlining && inlined_count_ > kMaxInlinedNodes) || | 5417 if (inlined_count_ > Min(FLAG_max_inlined_nodes_cumulative, |
5419 inlined_count_ > kUnlimitedMaxInlinedNodes) { | 5418 kUnlimitedMaxInlinedNodesCumulative)) { |
5420 TraceInline(target, caller, "cumulative AST node limit reached"); | 5419 TraceInline(target, caller, "cumulative AST node limit reached"); |
5421 return false; | 5420 return false; |
5422 } | 5421 } |
5423 | 5422 |
5424 // Parse and allocate variables. | 5423 // Parse and allocate variables. |
5425 CompilationInfo target_info(target); | 5424 CompilationInfo target_info(target); |
5426 if (!ParserApi::Parse(&target_info, kNoParsingFlags) || | 5425 if (!ParserApi::Parse(&target_info, kNoParsingFlags) || |
5427 !Scope::Analyze(&target_info)) { | 5426 !Scope::Analyze(&target_info)) { |
5428 if (target_info.isolate()->has_pending_exception()) { | 5427 if (target_info.isolate()->has_pending_exception()) { |
5429 // Parse or scope error, never optimize this function. | 5428 // Parse or scope error, never optimize this function. |
5430 SetStackOverflow(); | 5429 SetStackOverflow(); |
5431 target_shared->DisableOptimization(); | 5430 target_shared->DisableOptimization(); |
5432 } | 5431 } |
5433 TraceInline(target, caller, "parse failure"); | 5432 TraceInline(target, caller, "parse failure"); |
5434 return false; | 5433 return false; |
5435 } | 5434 } |
5436 | 5435 |
5437 if (target_info.scope()->num_heap_slots() > 0) { | 5436 if (target_info.scope()->num_heap_slots() > 0) { |
5438 TraceInline(target, caller, "target has context-allocated variables"); | 5437 TraceInline(target, caller, "target has context-allocated variables"); |
5439 return false; | 5438 return false; |
5440 } | 5439 } |
5441 FunctionLiteral* function = target_info.function(); | 5440 FunctionLiteral* function = target_info.function(); |
5442 | 5441 |
5443 // The following conditions must be checked again after re-parsing, because | 5442 // The following conditions must be checked again after re-parsing, because |
5444 // earlier the information might not have been complete due to lazy parsing. | 5443 // earlier the information might not have been complete due to lazy parsing. |
5445 nodes_added = function->ast_node_count(); | 5444 nodes_added = function->ast_node_count(); |
5446 if ((FLAG_limit_inlining && nodes_added > kMaxInlinedSize) || | 5445 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { |
5447 nodes_added > kUnlimitedMaxInlinedSize) { | |
5448 TraceInline(target, caller, "target AST is too large [late]"); | 5446 TraceInline(target, caller, "target AST is too large [late]"); |
5449 return false; | 5447 return false; |
5450 } | 5448 } |
5451 AstProperties::Flags* flags(function->flags()); | 5449 AstProperties::Flags* flags(function->flags()); |
5452 if (flags->Contains(kDontInline) || flags->Contains(kDontOptimize)) { | 5450 if (flags->Contains(kDontInline) || flags->Contains(kDontOptimize)) { |
5453 TraceInline(target, caller, "target contains unsupported syntax [late]"); | 5451 TraceInline(target, caller, "target contains unsupported syntax [late]"); |
5454 return false; | 5452 return false; |
5455 } | 5453 } |
5456 | 5454 |
5457 // If the function uses the arguments object check that inlining of functions | 5455 // If the function uses the arguments object check that inlining of functions |
(...skipping 2910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8368 } | 8366 } |
8369 } | 8367 } |
8370 | 8368 |
8371 #ifdef DEBUG | 8369 #ifdef DEBUG |
8372 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 8370 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
8373 if (allocator_ != NULL) allocator_->Verify(); | 8371 if (allocator_ != NULL) allocator_->Verify(); |
8374 #endif | 8372 #endif |
8375 } | 8373 } |
8376 | 8374 |
8377 } } // namespace v8::internal | 8375 } } // namespace v8::internal |
OLD | NEW |