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 |