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