Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/compiler.h" | 5 #include "src/compiler.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "src/ast/ast-numbering.h" | 9 #include "src/ast/ast-numbering.h" |
| 10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 481 time_taken_to_optimize_, | 481 time_taken_to_optimize_, |
| 482 time_taken_to_codegen_); | 482 time_taken_to_codegen_); |
| 483 } | 483 } |
| 484 } | 484 } |
| 485 | 485 |
| 486 // ---------------------------------------------------------------------------- | 486 // ---------------------------------------------------------------------------- |
| 487 // Local helper methods that make up the compilation pipeline. | 487 // Local helper methods that make up the compilation pipeline. |
| 488 | 488 |
| 489 namespace { | 489 namespace { |
| 490 | 490 |
| 491 // Sets the expected number of properties based on estimate from compiler. | |
| 492 void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared, | |
| 493 int estimate) { | |
| 494 // If no properties are added in the constructor, they are more likely | |
| 495 // to be added later. | |
| 496 if (estimate == 0) estimate = 2; | |
| 497 | |
| 498 // TODO(yangguo): check whether those heuristics are still up-to-date. | |
| 499 // We do not shrink objects that go into a snapshot (yet), so we adjust | |
| 500 // the estimate conservatively. | |
| 501 if (shared->GetIsolate()->serializer_enabled()) { | |
| 502 estimate += 2; | |
| 503 } else { | |
| 504 // Inobject slack tracking will reclaim redundant inobject space later, | |
| 505 // so we can afford to adjust the estimate generously. | |
| 506 estimate += 8; | |
| 507 } | |
| 508 | |
| 509 shared->set_expected_nof_properties(estimate); | |
| 510 } | |
| 511 | |
| 512 void MaybeDisableOptimization(Handle<SharedFunctionInfo> shared_info, | 491 void MaybeDisableOptimization(Handle<SharedFunctionInfo> shared_info, |
| 513 BailoutReason bailout_reason) { | 492 BailoutReason bailout_reason) { |
| 514 if (bailout_reason != kNoReason) { | 493 if (bailout_reason != kNoReason) { |
| 515 shared_info->DisableOptimization(bailout_reason); | 494 shared_info->DisableOptimization(bailout_reason); |
| 516 } | 495 } |
| 517 } | 496 } |
| 518 | 497 |
| 519 void RecordFunctionCompilation(Logger::LogEventsAndTags tag, | 498 void RecordFunctionCompilation(Logger::LogEventsAndTags tag, |
| 520 CompilationInfo* info, | 499 CompilationInfo* info, |
| 521 Handle<SharedFunctionInfo> shared) { | 500 Handle<SharedFunctionInfo> shared) { |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 656 | 635 |
| 657 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { | 636 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { |
| 658 VMState<COMPILER> state(info->isolate()); | 637 VMState<COMPILER> state(info->isolate()); |
| 659 PostponeInterruptsScope postpone(info->isolate()); | 638 PostponeInterruptsScope postpone(info->isolate()); |
| 660 | 639 |
| 661 // Parse and update CompilationInfo with the results. | 640 // Parse and update CompilationInfo with the results. |
| 662 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); | 641 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); |
| 663 Handle<SharedFunctionInfo> shared = info->shared_info(); | 642 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 664 FunctionLiteral* lit = info->literal(); | 643 FunctionLiteral* lit = info->literal(); |
| 665 DCHECK_EQ(shared->language_mode(), lit->language_mode()); | 644 DCHECK_EQ(shared->language_mode(), lit->language_mode()); |
| 666 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); | |
| 667 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); | 645 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); |
| 668 | 646 |
| 669 // Compile either unoptimized code or bytecode for the interpreter. | 647 // Compile either unoptimized code or bytecode for the interpreter. |
| 670 if (!CompileBaselineCode(info)) return MaybeHandle<Code>(); | 648 if (!CompileBaselineCode(info)) return MaybeHandle<Code>(); |
| 671 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); | 649 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); |
| 672 | 650 |
| 673 // Update the shared function info with the scope info. Allocating the | 651 // Update the shared function info with the scope info. Allocating the |
| 674 // ScopeInfo object may cause a GC. | 652 // ScopeInfo object may cause a GC. |
| 675 Handle<ScopeInfo> scope_info = | 653 Handle<ScopeInfo> scope_info = |
| 676 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); | 654 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 998 } | 976 } |
| 999 return true; | 977 return true; |
| 1000 } | 978 } |
| 1001 | 979 |
| 1002 inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { | 980 inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { |
| 1003 return shared->is_toplevel() && shared->script()->IsScript() && | 981 return shared->is_toplevel() && shared->script()->IsScript() && |
| 1004 Script::cast(shared->script())->compilation_type() == | 982 Script::cast(shared->script())->compilation_type() == |
| 1005 Script::COMPILATION_TYPE_EVAL; | 983 Script::COMPILATION_TYPE_EVAL; |
| 1006 } | 984 } |
| 1007 | 985 |
| 986 // Sets the expected number of properties based on estimate from parser. | |
| 987 void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared, | |
| 988 FunctionLiteral* literal) { | |
| 989 int estimate = literal->expected_property_count(); | |
| 990 | |
| 991 // If no properties are added in the constructor, they are more likely | |
| 992 // to be added later. | |
| 993 if (estimate == 0) estimate = 2; | |
| 994 | |
| 995 // TODO(yangguo): check whether those heuristics are still up-to-date. | |
| 996 // We do not shrink objects that go into a snapshot (yet), so we adjust | |
| 997 // the estimate conservatively. | |
| 998 if (shared->GetIsolate()->serializer_enabled()) { | |
| 999 estimate += 2; | |
| 1000 } else { | |
| 1001 // Inobject slack tracking will reclaim redundant inobject space later, | |
| 1002 // so we can afford to adjust the estimate generously. | |
| 1003 estimate += 8; | |
| 1004 } | |
| 1005 | |
| 1006 shared->set_expected_nof_properties(estimate); | |
| 1007 } | |
| 1008 | |
| 1008 Handle<SharedFunctionInfo> NewSharedFunctionInfoForLiteral( | 1009 Handle<SharedFunctionInfo> NewSharedFunctionInfoForLiteral( |
| 1009 Isolate* isolate, FunctionLiteral* literal, Handle<Script> script) { | 1010 Isolate* isolate, FunctionLiteral* literal, Handle<Script> script) { |
| 1010 Handle<Code> code = isolate->builtins()->CompileLazy(); | 1011 Handle<Code> code = isolate->builtins()->CompileLazy(); |
| 1011 Handle<ScopeInfo> scope_info = handle(ScopeInfo::Empty(isolate)); | 1012 Handle<ScopeInfo> scope_info = handle(ScopeInfo::Empty(isolate)); |
| 1012 Handle<SharedFunctionInfo> result = isolate->factory()->NewSharedFunctionInfo( | 1013 Handle<SharedFunctionInfo> result = isolate->factory()->NewSharedFunctionInfo( |
| 1013 literal->name(), literal->materialized_literal_count(), literal->kind(), | 1014 literal->name(), literal->materialized_literal_count(), literal->kind(), |
| 1014 code, scope_info); | 1015 code, scope_info); |
| 1015 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); | 1016 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); |
| 1016 SharedFunctionInfo::SetScript(result, script); | 1017 SharedFunctionInfo::SetScript(result, script); |
| 1018 SetExpectedNofPropertiesFromEstimate(result, literal); | |
|
Michael Starzinger
2016/04/11 13:32:42
This could even be moved out of "compiler.cc" enti
Toon Verwaest
2016/04/11 13:43:32
That sounds good. The helper function used to be i
Michael Starzinger
2016/04/11 14:17:31
Done.
| |
| 1017 return result; | 1019 return result; |
| 1018 } | 1020 } |
| 1019 | 1021 |
| 1020 Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { | 1022 Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { |
| 1021 Isolate* isolate = info->isolate(); | 1023 Isolate* isolate = info->isolate(); |
| 1022 TimerEventScope<TimerEventCompileCode> timer(isolate); | 1024 TimerEventScope<TimerEventCompileCode> timer(isolate); |
| 1023 TRACE_EVENT0("v8", "V8.CompileCode"); | 1025 TRACE_EVENT0("v8", "V8.CompileCode"); |
| 1024 PostponeInterruptsScope postpone(isolate); | 1026 PostponeInterruptsScope postpone(isolate); |
| 1025 DCHECK(!isolate->native_context().is_null()); | 1027 DCHECK(!isolate->native_context().is_null()); |
| 1026 ParseInfo* parse_info = info->parse_info(); | 1028 ParseInfo* parse_info = info->parse_info(); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1113 script->name()->IsString() | 1115 script->name()->IsString() |
| 1114 ? Handle<String>(String::cast(script->name())) | 1116 ? Handle<String>(String::cast(script->name())) |
| 1115 : isolate->factory()->empty_string(); | 1117 : isolate->factory()->empty_string(); |
| 1116 Logger::LogEventsAndTags log_tag = info->is_eval() | 1118 Logger::LogEventsAndTags log_tag = info->is_eval() |
| 1117 ? Logger::EVAL_TAG | 1119 ? Logger::EVAL_TAG |
| 1118 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script); | 1120 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script); |
| 1119 | 1121 |
| 1120 PROFILE(isolate, CodeCreateEvent(log_tag, *info->abstract_code(), *result, | 1122 PROFILE(isolate, CodeCreateEvent(log_tag, *info->abstract_code(), *result, |
| 1121 info, *script_name)); | 1123 info, *script_name)); |
| 1122 | 1124 |
| 1123 // Hint to the runtime system used when allocating space for initial | |
| 1124 // property space by setting the expected number of properties for | |
| 1125 // the instances of the function. | |
| 1126 SetExpectedNofPropertiesFromEstimate(result, | |
| 1127 lit->expected_property_count()); | |
| 1128 | |
| 1129 if (!script.is_null()) | 1125 if (!script.is_null()) |
| 1130 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED); | 1126 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED); |
| 1131 | 1127 |
| 1132 live_edit_tracker.RecordFunctionInfo(result, lit, info->zone()); | 1128 live_edit_tracker.RecordFunctionInfo(result, lit, info->zone()); |
| 1133 } | 1129 } |
| 1134 | 1130 |
| 1135 return result; | 1131 return result; |
| 1136 } | 1132 } |
| 1137 | 1133 |
| 1138 } // namespace | 1134 } // namespace |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1601 if (maybe_existing.is_null()) { | 1597 if (maybe_existing.is_null()) { |
| 1602 // If the outer function has been compiled before, we cannot be sure that | 1598 // If the outer function has been compiled before, we cannot be sure that |
| 1603 // shared function info for this function literal has been created for the | 1599 // shared function info for this function literal has been created for the |
| 1604 // first time. It may have already been compiled previously. | 1600 // first time. It may have already been compiled previously. |
| 1605 result->set_never_compiled(outer_info->is_first_compile() && lazy); | 1601 result->set_never_compiled(outer_info->is_first_compile() && lazy); |
| 1606 | 1602 |
| 1607 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); | 1603 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); |
| 1608 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); | 1604 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); |
| 1609 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); | 1605 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); |
| 1610 | 1606 |
| 1611 // Set the expected number of properties for instances and return | |
| 1612 // the resulting function. | |
| 1613 SetExpectedNofPropertiesFromEstimate(result, | |
| 1614 literal->expected_property_count()); | |
| 1615 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); | 1607 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); |
| 1616 } | 1608 } |
| 1617 | 1609 |
| 1618 return result; | 1610 return result; |
| 1619 } | 1611 } |
| 1620 | 1612 |
| 1621 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( | 1613 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( |
| 1622 v8::Extension* extension, Handle<String> name) { | 1614 v8::Extension* extension, Handle<String> name) { |
| 1623 Isolate* isolate = name->GetIsolate(); | 1615 Isolate* isolate = name->GetIsolate(); |
| 1624 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); | 1616 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1740 MaybeHandle<Code> code; | 1732 MaybeHandle<Code> code; |
| 1741 if (cached.code != nullptr) code = handle(cached.code); | 1733 if (cached.code != nullptr) code = handle(cached.code); |
| 1742 Handle<Context> native_context(function->context()->native_context()); | 1734 Handle<Context> native_context(function->context()->native_context()); |
| 1743 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | 1735 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, |
| 1744 literals, BailoutId::None()); | 1736 literals, BailoutId::None()); |
| 1745 } | 1737 } |
| 1746 } | 1738 } |
| 1747 | 1739 |
| 1748 } // namespace internal | 1740 } // namespace internal |
| 1749 } // namespace v8 | 1741 } // namespace v8 |
| OLD | NEW |