| 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 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 | 649 |
| 650 // Parsing is not required when optimizing from existing bytecode. | 650 // Parsing is not required when optimizing from existing bytecode. |
| 651 if (!info->is_optimizing_from_bytecode()) { | 651 if (!info->is_optimizing_from_bytecode()) { |
| 652 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; | 652 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
| 653 EnsureFeedbackMetadata(info); | 653 EnsureFeedbackMetadata(info); |
| 654 } | 654 } |
| 655 | 655 |
| 656 JSFunction::EnsureLiterals(info->closure()); | 656 JSFunction::EnsureLiterals(info->closure()); |
| 657 | 657 |
| 658 TimerEventScope<TimerEventRecompileSynchronous> timer(isolate); | 658 TimerEventScope<TimerEventRecompileSynchronous> timer(isolate); |
| 659 RuntimeCallTimerScope runtimeTimer(isolate, |
| 660 &RuntimeCallStats::RecompileSynchronous); |
| 659 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); | 661 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); |
| 660 | 662 |
| 661 if (job->CreateGraph() != CompilationJob::SUCCEEDED || | 663 if (job->CreateGraph() != CompilationJob::SUCCEEDED || |
| 662 job->OptimizeGraph() != CompilationJob::SUCCEEDED || | 664 job->OptimizeGraph() != CompilationJob::SUCCEEDED || |
| 663 job->GenerateCode() != CompilationJob::SUCCEEDED) { | 665 job->GenerateCode() != CompilationJob::SUCCEEDED) { |
| 664 if (FLAG_trace_opt) { | 666 if (FLAG_trace_opt) { |
| 665 PrintF("[aborted optimizing "); | 667 PrintF("[aborted optimizing "); |
| 666 info->closure()->ShortPrint(); | 668 info->closure()->ShortPrint(); |
| 667 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); | 669 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
| 668 } | 670 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 EnsureFeedbackMetadata(info); | 702 EnsureFeedbackMetadata(info); |
| 701 } | 703 } |
| 702 | 704 |
| 703 JSFunction::EnsureLiterals(info->closure()); | 705 JSFunction::EnsureLiterals(info->closure()); |
| 704 | 706 |
| 705 // Reopen handles in the new CompilationHandleScope. | 707 // Reopen handles in the new CompilationHandleScope. |
| 706 info->ReopenHandlesInNewHandleScope(); | 708 info->ReopenHandlesInNewHandleScope(); |
| 707 info->parse_info()->ReopenHandlesInNewHandleScope(); | 709 info->parse_info()->ReopenHandlesInNewHandleScope(); |
| 708 | 710 |
| 709 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); | 711 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
| 712 RuntimeCallTimerScope runtimeTimer(info->isolate(), |
| 713 &RuntimeCallStats::RecompileSynchronous); |
| 710 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); | 714 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); |
| 711 | 715 |
| 712 if (job->CreateGraph() != CompilationJob::SUCCEEDED) return false; | 716 if (job->CreateGraph() != CompilationJob::SUCCEEDED) return false; |
| 713 isolate->optimizing_compile_dispatcher()->QueueForOptimization(job); | 717 isolate->optimizing_compile_dispatcher()->QueueForOptimization(job); |
| 714 | 718 |
| 715 if (FLAG_trace_concurrent_recompilation) { | 719 if (FLAG_trace_concurrent_recompilation) { |
| 716 PrintF(" ** Queued "); | 720 PrintF(" ** Queued "); |
| 717 info->closure()->ShortPrint(); | 721 info->closure()->ShortPrint(); |
| 718 PrintF(" for concurrent optimization.\n"); | 722 PrintF(" for concurrent optimization.\n"); |
| 719 } | 723 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 // Limit the number of times we try to optimize functions. | 771 // Limit the number of times we try to optimize functions. |
| 768 const int kMaxOptCount = | 772 const int kMaxOptCount = |
| 769 FLAG_deopt_every_n_times == 0 ? FLAG_max_opt_count : 1000; | 773 FLAG_deopt_every_n_times == 0 ? FLAG_max_opt_count : 1000; |
| 770 if (info->shared_info()->opt_count() > kMaxOptCount) { | 774 if (info->shared_info()->opt_count() > kMaxOptCount) { |
| 771 info->AbortOptimization(kOptimizedTooManyTimes); | 775 info->AbortOptimization(kOptimizedTooManyTimes); |
| 772 return MaybeHandle<Code>(); | 776 return MaybeHandle<Code>(); |
| 773 } | 777 } |
| 774 | 778 |
| 775 CanonicalHandleScope canonical(isolate); | 779 CanonicalHandleScope canonical(isolate); |
| 776 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); | 780 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); |
| 781 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::OptimizeCode); |
| 777 TRACE_EVENT0("v8", "V8.OptimizeCode"); | 782 TRACE_EVENT0("v8", "V8.OptimizeCode"); |
| 778 | 783 |
| 779 // TurboFan can optimize directly from existing bytecode. | 784 // TurboFan can optimize directly from existing bytecode. |
| 780 if (FLAG_turbo_from_bytecode && use_turbofan && | 785 if (FLAG_turbo_from_bytecode && use_turbofan && |
| 781 info->shared_info()->HasBytecodeArray()) { | 786 info->shared_info()->HasBytecodeArray()) { |
| 782 info->MarkAsOptimizeFromBytecode(); | 787 info->MarkAsOptimizeFromBytecode(); |
| 783 } | 788 } |
| 784 | 789 |
| 785 if (IsEvalToplevel(shared)) { | 790 if (IsEvalToplevel(shared)) { |
| 786 parse_info->set_eval(); | 791 parse_info->set_eval(); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, &info); | 960 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, &info); |
| 956 | 961 |
| 957 return info.code(); | 962 return info.code(); |
| 958 } | 963 } |
| 959 | 964 |
| 960 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { | 965 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { |
| 961 Isolate* isolate = function->GetIsolate(); | 966 Isolate* isolate = function->GetIsolate(); |
| 962 DCHECK(!isolate->has_pending_exception()); | 967 DCHECK(!isolate->has_pending_exception()); |
| 963 DCHECK(!function->is_compiled()); | 968 DCHECK(!function->is_compiled()); |
| 964 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); | 969 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); |
| 970 RuntimeCallTimerScope runtimeTimer(isolate, |
| 971 &RuntimeCallStats::CompileCodeLazy); |
| 965 TRACE_EVENT0("v8", "V8.CompileCode"); | 972 TRACE_EVENT0("v8", "V8.CompileCode"); |
| 966 AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy()); | 973 AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy()); |
| 967 | 974 |
| 968 if (FLAG_turbo_cache_shared_code) { | 975 if (FLAG_turbo_cache_shared_code) { |
| 969 Handle<Code> cached_code; | 976 Handle<Code> cached_code; |
| 970 if (GetCodeFromOptimizedCodeMap(function, BailoutId::None()) | 977 if (GetCodeFromOptimizedCodeMap(function, BailoutId::None()) |
| 971 .ToHandle(&cached_code)) { | 978 .ToHandle(&cached_code)) { |
| 972 if (FLAG_trace_opt) { | 979 if (FLAG_trace_opt) { |
| 973 PrintF("[found optimized code for "); | 980 PrintF("[found optimized code for "); |
| 974 function->ShortPrint(); | 981 function->ShortPrint(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 literal->name(), literal->materialized_literal_count(), literal->kind(), | 1016 literal->name(), literal->materialized_literal_count(), literal->kind(), |
| 1010 code, scope_info); | 1017 code, scope_info); |
| 1011 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); | 1018 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); |
| 1012 SharedFunctionInfo::SetScript(result, script); | 1019 SharedFunctionInfo::SetScript(result, script); |
| 1013 return result; | 1020 return result; |
| 1014 } | 1021 } |
| 1015 | 1022 |
| 1016 Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { | 1023 Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { |
| 1017 Isolate* isolate = info->isolate(); | 1024 Isolate* isolate = info->isolate(); |
| 1018 TimerEventScope<TimerEventCompileCode> timer(isolate); | 1025 TimerEventScope<TimerEventCompileCode> timer(isolate); |
| 1026 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::CompileCode); |
| 1019 TRACE_EVENT0("v8", "V8.CompileCode"); | 1027 TRACE_EVENT0("v8", "V8.CompileCode"); |
| 1020 PostponeInterruptsScope postpone(isolate); | 1028 PostponeInterruptsScope postpone(isolate); |
| 1021 DCHECK(!isolate->native_context().is_null()); | 1029 DCHECK(!isolate->native_context().is_null()); |
| 1022 ParseInfo* parse_info = info->parse_info(); | 1030 ParseInfo* parse_info = info->parse_info(); |
| 1023 Handle<Script> script = parse_info->script(); | 1031 Handle<Script> script = parse_info->script(); |
| 1024 | 1032 |
| 1025 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? | 1033 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? |
| 1026 FixedArray* array = isolate->native_context()->embedder_data(); | 1034 FixedArray* array = isolate->native_context()->embedder_data(); |
| 1027 script->set_context_data(array->get(v8::Context::kDebugIdIndex)); | 1035 script->set_context_data(array->get(v8::Context::kDebugIdIndex)); |
| 1028 | 1036 |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1474 if (extension == NULL) { | 1482 if (extension == NULL) { |
| 1475 // First check per-isolate compilation cache. | 1483 // First check per-isolate compilation cache. |
| 1476 maybe_result = compilation_cache->LookupScript( | 1484 maybe_result = compilation_cache->LookupScript( |
| 1477 source, script_name, line_offset, column_offset, resource_options, | 1485 source, script_name, line_offset, column_offset, resource_options, |
| 1478 context, language_mode); | 1486 context, language_mode); |
| 1479 if (maybe_result.is_null() && FLAG_serialize_toplevel && | 1487 if (maybe_result.is_null() && FLAG_serialize_toplevel && |
| 1480 compile_options == ScriptCompiler::kConsumeCodeCache && | 1488 compile_options == ScriptCompiler::kConsumeCodeCache && |
| 1481 !isolate->debug()->is_loaded()) { | 1489 !isolate->debug()->is_loaded()) { |
| 1482 // Then check cached code provided by embedder. | 1490 // Then check cached code provided by embedder. |
| 1483 HistogramTimerScope timer(isolate->counters()->compile_deserialize()); | 1491 HistogramTimerScope timer(isolate->counters()->compile_deserialize()); |
| 1492 RuntimeCallTimerScope runtimeTimer(isolate, |
| 1493 &RuntimeCallStats::CompileDeserialize); |
| 1484 TRACE_EVENT0("v8", "V8.CompileDeserialize"); | 1494 TRACE_EVENT0("v8", "V8.CompileDeserialize"); |
| 1485 Handle<SharedFunctionInfo> result; | 1495 Handle<SharedFunctionInfo> result; |
| 1486 if (CodeSerializer::Deserialize(isolate, *cached_data, source) | 1496 if (CodeSerializer::Deserialize(isolate, *cached_data, source) |
| 1487 .ToHandle(&result)) { | 1497 .ToHandle(&result)) { |
| 1488 // Promote to per-isolate compilation cache. | 1498 // Promote to per-isolate compilation cache. |
| 1489 compilation_cache->PutScript(source, context, language_mode, result); | 1499 compilation_cache->PutScript(source, context, language_mode, result); |
| 1490 return result; | 1500 return result; |
| 1491 } | 1501 } |
| 1492 // Deserializer failed. Fall through to compile. | 1502 // Deserializer failed. Fall through to compile. |
| 1493 } | 1503 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1545 | 1555 |
| 1546 parse_info.set_language_mode( | 1556 parse_info.set_language_mode( |
| 1547 static_cast<LanguageMode>(parse_info.language_mode() | language_mode)); | 1557 static_cast<LanguageMode>(parse_info.language_mode() | language_mode)); |
| 1548 result = CompileToplevel(&info); | 1558 result = CompileToplevel(&info); |
| 1549 if (extension == NULL && !result.is_null()) { | 1559 if (extension == NULL && !result.is_null()) { |
| 1550 compilation_cache->PutScript(source, context, language_mode, result); | 1560 compilation_cache->PutScript(source, context, language_mode, result); |
| 1551 if (FLAG_serialize_toplevel && | 1561 if (FLAG_serialize_toplevel && |
| 1552 compile_options == ScriptCompiler::kProduceCodeCache) { | 1562 compile_options == ScriptCompiler::kProduceCodeCache) { |
| 1553 HistogramTimerScope histogram_timer( | 1563 HistogramTimerScope histogram_timer( |
| 1554 isolate->counters()->compile_serialize()); | 1564 isolate->counters()->compile_serialize()); |
| 1565 RuntimeCallTimerScope runtimeTimer(isolate, |
| 1566 &RuntimeCallStats::CompileSerialize); |
| 1555 TRACE_EVENT0("v8", "V8.CompileSerialize"); | 1567 TRACE_EVENT0("v8", "V8.CompileSerialize"); |
| 1556 *cached_data = CodeSerializer::Serialize(isolate, result, source); | 1568 *cached_data = CodeSerializer::Serialize(isolate, result, source); |
| 1557 if (FLAG_profile_deserialization) { | 1569 if (FLAG_profile_deserialization) { |
| 1558 PrintF("[Compiling and serializing took %0.3f ms]\n", | 1570 PrintF("[Compiling and serializing took %0.3f ms]\n", |
| 1559 timer.Elapsed().InMillisecondsF()); | 1571 timer.Elapsed().InMillisecondsF()); |
| 1560 } | 1572 } |
| 1561 } | 1573 } |
| 1562 } | 1574 } |
| 1563 | 1575 |
| 1564 if (result.is_null()) { | 1576 if (result.is_null()) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1661 | 1673 |
| 1662 // Consider compiling eagerly when targeting the code cache. | 1674 // Consider compiling eagerly when targeting the code cache. |
| 1663 lazy &= !(FLAG_serialize_eager && info.will_serialize()); | 1675 lazy &= !(FLAG_serialize_eager && info.will_serialize()); |
| 1664 | 1676 |
| 1665 // Consider compiling eagerly when compiling bytecode for Ignition. | 1677 // Consider compiling eagerly when compiling bytecode for Ignition. |
| 1666 lazy &= | 1678 lazy &= |
| 1667 !(FLAG_ignition && FLAG_ignition_eager && !isolate->serializer_enabled()); | 1679 !(FLAG_ignition && FLAG_ignition_eager && !isolate->serializer_enabled()); |
| 1668 | 1680 |
| 1669 // Generate code | 1681 // Generate code |
| 1670 TimerEventScope<TimerEventCompileCode> timer(isolate); | 1682 TimerEventScope<TimerEventCompileCode> timer(isolate); |
| 1683 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::CompileCode); |
| 1671 TRACE_EVENT0("v8", "V8.CompileCode"); | 1684 TRACE_EVENT0("v8", "V8.CompileCode"); |
| 1672 if (lazy) { | 1685 if (lazy) { |
| 1673 info.SetCode(isolate->builtins()->CompileLazy()); | 1686 info.SetCode(isolate->builtins()->CompileLazy()); |
| 1674 } else if (Renumber(info.parse_info()) && GenerateUnoptimizedCode(&info)) { | 1687 } else if (Renumber(info.parse_info()) && GenerateUnoptimizedCode(&info)) { |
| 1675 // Code generation will ensure that the feedback vector is present and | 1688 // Code generation will ensure that the feedback vector is present and |
| 1676 // appropriately sized. | 1689 // appropriately sized. |
| 1677 DCHECK(!info.code().is_null()); | 1690 DCHECK(!info.code().is_null()); |
| 1678 if (literal->should_eager_compile() && | 1691 if (literal->should_eager_compile() && |
| 1679 literal->should_be_used_once_hint()) { | 1692 literal->should_be_used_once_hint()) { |
| 1680 info.code()->MarkToBeExecutedOnce(isolate); | 1693 info.code()->MarkToBeExecutedOnce(isolate); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1734 } | 1747 } |
| 1735 | 1748 |
| 1736 void Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { | 1749 void Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { |
| 1737 // Take ownership of compilation job. Deleting job also tears down the zone. | 1750 // Take ownership of compilation job. Deleting job also tears down the zone. |
| 1738 base::SmartPointer<CompilationJob> job(raw_job); | 1751 base::SmartPointer<CompilationJob> job(raw_job); |
| 1739 CompilationInfo* info = job->info(); | 1752 CompilationInfo* info = job->info(); |
| 1740 Isolate* isolate = info->isolate(); | 1753 Isolate* isolate = info->isolate(); |
| 1741 | 1754 |
| 1742 VMState<COMPILER> state(isolate); | 1755 VMState<COMPILER> state(isolate); |
| 1743 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); | 1756 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
| 1757 RuntimeCallTimerScope runtimeTimer(isolate, |
| 1758 &RuntimeCallStats::RecompileSynchronous); |
| 1744 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); | 1759 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); |
| 1745 | 1760 |
| 1746 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1761 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 1747 shared->code()->set_profiler_ticks(0); | 1762 shared->code()->set_profiler_ticks(0); |
| 1748 | 1763 |
| 1749 DCHECK(!shared->HasDebugInfo()); | 1764 DCHECK(!shared->HasDebugInfo()); |
| 1750 | 1765 |
| 1751 // 1) Optimization on the concurrent thread may have failed. | 1766 // 1) Optimization on the concurrent thread may have failed. |
| 1752 // 2) The function may have already been optimized by OSR. Simply continue. | 1767 // 2) The function may have already been optimized by OSR. Simply continue. |
| 1753 // Except when OSR already disabled optimization for some reason. | 1768 // Except when OSR already disabled optimization for some reason. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1805 DCHECK(shared->is_compiled()); | 1820 DCHECK(shared->is_compiled()); |
| 1806 function->set_literals(cached.literals); | 1821 function->set_literals(cached.literals); |
| 1807 } else if (shared->is_compiled()) { | 1822 } else if (shared->is_compiled()) { |
| 1808 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1823 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
| 1809 JSFunction::EnsureLiterals(function); | 1824 JSFunction::EnsureLiterals(function); |
| 1810 } | 1825 } |
| 1811 } | 1826 } |
| 1812 | 1827 |
| 1813 } // namespace internal | 1828 } // namespace internal |
| 1814 } // namespace v8 | 1829 } // namespace v8 |
| OLD | NEW |