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 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 932 | 932 |
| 933 // Install compilation result on the shared function info | 933 // Install compilation result on the shared function info |
| 934 InstallSharedCompilationResult(&info, shared); | 934 InstallSharedCompilationResult(&info, shared); |
| 935 | 935 |
| 936 // Record the function compilation event. | 936 // Record the function compilation event. |
| 937 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &info); | 937 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &info); |
| 938 | 938 |
| 939 return info.code(); | 939 return info.code(); |
| 940 } | 940 } |
| 941 | 941 |
| 942 bool ShouldOptimizeForAsm(Isolate* isolate, Handle<JSFunction> function) { | |
| 943 // If the debugger is active, do not compile with turbofan unless we can | |
| 944 // deopt from turbofan code. | |
| 945 return FLAG_turbo_asm && function->shared()->asm_function() && | |
| 946 (FLAG_turbo_asm_deoptimization || !isolate->debug()->is_active()); | |
| 947 } | |
| 948 | |
| 942 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { | 949 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { |
| 943 Isolate* isolate = function->GetIsolate(); | 950 Isolate* isolate = function->GetIsolate(); |
| 944 DCHECK(!isolate->has_pending_exception()); | 951 DCHECK(!isolate->has_pending_exception()); |
| 945 DCHECK(!function->is_compiled()); | 952 DCHECK(!function->is_compiled()); |
| 946 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); | 953 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); |
| 947 TRACE_EVENT0("v8", "V8.CompileCode"); | 954 TRACE_EVENT0("v8", "V8.CompileCode"); |
| 948 AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy()); | 955 AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy()); |
| 949 | 956 |
| 950 if (FLAG_turbo_cache_shared_code) { | 957 if (FLAG_turbo_cache_shared_code) { |
| 951 Handle<Code> cached_code; | 958 Handle<Code> cached_code; |
| 952 if (GetCodeFromOptimizedCodeMap(function, BailoutId::None()) | 959 if (GetCodeFromOptimizedCodeMap(function, BailoutId::None()) |
| 953 .ToHandle(&cached_code)) { | 960 .ToHandle(&cached_code)) { |
| 954 if (FLAG_trace_opt) { | 961 if (FLAG_trace_opt) { |
| 955 PrintF("[found optimized code for "); | 962 PrintF("[found optimized code for "); |
| 956 function->ShortPrint(); | 963 function->ShortPrint(); |
| 957 PrintF(" during unoptimized compile]\n"); | 964 PrintF(" during unoptimized compile]\n"); |
| 958 } | 965 } |
| 959 DCHECK(function->shared()->is_compiled()); | 966 DCHECK(function->shared()->is_compiled()); |
| 960 return cached_code; | 967 return cached_code; |
| 961 } | 968 } |
| 962 } | 969 } |
| 963 | 970 |
| 964 if (function->shared()->is_compiled()) { | 971 if (function->shared()->is_compiled()) { |
| 965 return Handle<Code>(function->shared()->code()); | 972 return Handle<Code>(function->shared()->code()); |
| 966 } | 973 } |
| 967 | 974 |
| 975 if (FLAG_always_opt || ShouldOptimizeForAsm(isolate, function)) { | |
| 976 Handle<Code> opt_code; | |
| 977 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) | |
| 978 .ToHandle(&opt_code)) { | |
| 979 DCHECK(function->shared()->is_compiled()); | |
| 980 return opt_code; | |
| 981 } | |
| 982 } | |
| 983 | |
| 968 Zone zone(isolate->allocator()); | 984 Zone zone(isolate->allocator()); |
| 969 ParseInfo parse_info(&zone, function); | 985 ParseInfo parse_info(&zone, function); |
| 970 CompilationInfo info(&parse_info, function); | 986 CompilationInfo info(&parse_info, function); |
| 971 Handle<Code> result; | 987 Handle<Code> result; |
| 972 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCode(&info), Code); | 988 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCode(&info), Code); |
| 973 | 989 |
| 974 if (FLAG_always_opt) { | |
| 975 Handle<Code> opt_code; | |
| 976 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) | |
| 977 .ToHandle(&opt_code)) { | |
| 978 result = opt_code; | |
| 979 } | |
| 980 } | |
| 981 | |
| 982 return result; | 990 return result; |
| 983 } | 991 } |
| 984 | 992 |
| 993 bool GetEagerCode(CompilationInfo* info) { | |
|
rmcilroy
2016/05/20 10:04:16
I factored this code out of NewSharedFunctionInfoF
| |
| 994 Isolate* isolate = info->isolate(); | |
| 995 DCHECK(!isolate->has_pending_exception()); | |
| 996 DCHECK(info->code().is_null()); | |
| 997 DCHECK_NOT_NULL(info->literal()); | |
| 998 DCHECK_NOT_NULL(info->scope()); | |
| 999 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); | |
| 1000 TRACE_EVENT0("v8", "V8.CompileCode"); | |
| 1001 | |
| 1002 if (!Renumber(info->parse_info()) || !GenerateUnoptimizedCode(info)) { | |
| 1003 return false; | |
| 1004 } | |
| 1005 | |
| 1006 // Code generation will ensure that the feedback vector is present and | |
| 1007 // appropriately sized. | |
| 1008 DCHECK(!info->code().is_null()); | |
| 1009 | |
| 1010 if (info->literal()->should_eager_compile() && | |
| 1011 info->literal()->should_be_used_once_hint()) { | |
| 1012 info->code()->MarkToBeExecutedOnce(isolate); | |
| 1013 } | |
| 1014 | |
| 1015 // Update the shared function info with the scope info. | |
| 1016 InstallSharedScopeInfo(info, info->shared_info()); | |
| 1017 // Install compilation result on the shared function info. | |
| 1018 InstallSharedCompilationResult(info, info->shared_info()); | |
| 1019 | |
| 1020 return true; | |
| 1021 } | |
| 985 | 1022 |
| 986 Handle<SharedFunctionInfo> NewSharedFunctionInfoForLiteral( | 1023 Handle<SharedFunctionInfo> NewSharedFunctionInfoForLiteral( |
| 987 Isolate* isolate, FunctionLiteral* literal, Handle<Script> script) { | 1024 Isolate* isolate, FunctionLiteral* literal, Handle<Script> script) { |
| 988 Handle<Code> code = isolate->builtins()->CompileLazy(); | 1025 Handle<Code> code = isolate->builtins()->CompileLazy(); |
| 989 Handle<ScopeInfo> scope_info = handle(ScopeInfo::Empty(isolate)); | 1026 Handle<ScopeInfo> scope_info = handle(ScopeInfo::Empty(isolate)); |
| 990 Handle<SharedFunctionInfo> result = isolate->factory()->NewSharedFunctionInfo( | 1027 Handle<SharedFunctionInfo> result = isolate->factory()->NewSharedFunctionInfo( |
| 991 literal->name(), literal->materialized_literal_count(), literal->kind(), | 1028 literal->name(), literal->materialized_literal_count(), literal->kind(), |
| 992 code, scope_info); | 1029 code, scope_info); |
| 993 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); | 1030 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); |
| 994 SharedFunctionInfo::SetScript(result, script); | 1031 SharedFunctionInfo::SetScript(result, script); |
| (...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1637 bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile(); | 1674 bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile(); |
| 1638 | 1675 |
| 1639 // Consider compiling eagerly when targeting the code cache. | 1676 // Consider compiling eagerly when targeting the code cache. |
| 1640 lazy &= !(FLAG_serialize_eager && info.will_serialize()); | 1677 lazy &= !(FLAG_serialize_eager && info.will_serialize()); |
| 1641 | 1678 |
| 1642 // Consider compiling eagerly when compiling bytecode for Ignition. | 1679 // Consider compiling eagerly when compiling bytecode for Ignition. |
| 1643 lazy &= | 1680 lazy &= |
| 1644 !(FLAG_ignition && FLAG_ignition_eager && !isolate->serializer_enabled()); | 1681 !(FLAG_ignition && FLAG_ignition_eager && !isolate->serializer_enabled()); |
| 1645 | 1682 |
| 1646 // Generate code | 1683 // Generate code |
| 1647 TimerEventScope<TimerEventCompileCode> timer(isolate); | |
| 1648 TRACE_EVENT0("v8", "V8.CompileCode"); | |
| 1649 if (lazy) { | 1684 if (lazy) { |
| 1650 info.SetCode(isolate->builtins()->CompileLazy()); | 1685 info.SetCode(isolate->builtins()->CompileLazy()); |
| 1651 } else if (Renumber(info.parse_info()) && GenerateUnoptimizedCode(&info)) { | 1686 } else if (!GetEagerCode(&info)) { |
| 1652 // Code generation will ensure that the feedback vector is present and | |
| 1653 // appropriately sized. | |
| 1654 DCHECK(!info.code().is_null()); | |
| 1655 if (literal->should_eager_compile() && | |
| 1656 literal->should_be_used_once_hint()) { | |
| 1657 info.code()->MarkToBeExecutedOnce(isolate); | |
| 1658 } | |
| 1659 // Update the shared function info with the scope info. | |
| 1660 InstallSharedScopeInfo(&info, result); | |
| 1661 // Install compilation result on the shared function info. | |
| 1662 InstallSharedCompilationResult(&info, result); | |
| 1663 } else { | |
| 1664 return Handle<SharedFunctionInfo>::null(); | 1687 return Handle<SharedFunctionInfo>::null(); |
| 1665 } | 1688 } |
| 1666 | 1689 |
| 1667 if (maybe_existing.is_null()) { | 1690 if (maybe_existing.is_null()) { |
| 1668 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info); | 1691 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info); |
| 1669 } | 1692 } |
| 1670 | 1693 |
| 1671 return result; | 1694 return result; |
| 1672 } | 1695 } |
| 1673 | 1696 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1757 if (FLAG_trace_opt) { | 1780 if (FLAG_trace_opt) { |
| 1758 PrintF("[aborted optimizing "); | 1781 PrintF("[aborted optimizing "); |
| 1759 info->closure()->ShortPrint(); | 1782 info->closure()->ShortPrint(); |
| 1760 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); | 1783 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
| 1761 } | 1784 } |
| 1762 info->closure()->ReplaceCode(shared->code()); | 1785 info->closure()->ReplaceCode(shared->code()); |
| 1763 } | 1786 } |
| 1764 | 1787 |
| 1765 void Compiler::PostInstantiation(Handle<JSFunction> function, | 1788 void Compiler::PostInstantiation(Handle<JSFunction> function, |
| 1766 PretenureFlag pretenure) { | 1789 PretenureFlag pretenure) { |
| 1790 Isolate* isolate = function->GetIsolate(); | |
| 1767 Handle<SharedFunctionInfo> shared(function->shared()); | 1791 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1768 | 1792 |
| 1769 if (FLAG_always_opt && shared->allows_lazy_compilation()) { | 1793 if ((FLAG_always_opt || ShouldOptimizeForAsm(isolate, function)) && |
| 1794 shared->allows_lazy_compilation()) { | |
| 1770 function->MarkForOptimization(); | 1795 function->MarkForOptimization(); |
| 1771 } | 1796 } |
| 1772 | 1797 |
| 1773 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( | 1798 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( |
| 1774 function->context()->native_context(), BailoutId::None()); | 1799 function->context()->native_context(), BailoutId::None()); |
| 1775 if (cached.code != nullptr) { | 1800 if (cached.code != nullptr) { |
| 1776 // Caching of optimized code enabled and optimized code found. | 1801 // Caching of optimized code enabled and optimized code found. |
| 1777 DCHECK(!cached.code->marked_for_deoptimization()); | 1802 DCHECK(!cached.code->marked_for_deoptimization()); |
| 1778 DCHECK(function->shared()->is_compiled()); | 1803 DCHECK(function->shared()->is_compiled()); |
| 1779 function->ReplaceCode(cached.code); | 1804 function->ReplaceCode(cached.code); |
| 1780 } | 1805 } |
| 1781 | 1806 |
| 1782 if (cached.literals != nullptr) { | 1807 if (cached.literals != nullptr) { |
| 1783 function->set_literals(cached.literals); | 1808 function->set_literals(cached.literals); |
| 1784 } else { | 1809 } else { |
| 1785 Isolate* isolate = function->GetIsolate(); | |
| 1786 int number_of_literals = shared->num_literals(); | 1810 int number_of_literals = shared->num_literals(); |
| 1787 Handle<LiteralsArray> literals = | 1811 Handle<LiteralsArray> literals = |
| 1788 LiteralsArray::New(isolate, handle(shared->feedback_vector()), | 1812 LiteralsArray::New(isolate, handle(shared->feedback_vector()), |
| 1789 number_of_literals, pretenure); | 1813 number_of_literals, pretenure); |
| 1790 function->set_literals(*literals); | 1814 function->set_literals(*literals); |
| 1791 | 1815 |
| 1792 // Cache context-specific literals. | 1816 // Cache context-specific literals. |
| 1793 MaybeHandle<Code> code; | 1817 MaybeHandle<Code> code; |
| 1794 if (cached.code != nullptr) code = handle(cached.code); | 1818 if (cached.code != nullptr) code = handle(cached.code); |
| 1795 Handle<Context> native_context(function->context()->native_context()); | 1819 Handle<Context> native_context(function->context()->native_context()); |
| 1796 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | 1820 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, |
| 1797 literals, BailoutId::None()); | 1821 literals, BailoutId::None()); |
| 1798 } | 1822 } |
| 1799 } | 1823 } |
| 1800 | 1824 |
| 1801 } // namespace internal | 1825 } // namespace internal |
| 1802 } // namespace v8 | 1826 } // namespace v8 |
| OLD | NEW |