| 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" |
| 11 #include "src/ast/scopeinfo.h" | 11 #include "src/ast/scopeinfo.h" |
| 12 #include "src/ast/scopes.h" | 12 #include "src/ast/scopes.h" |
| 13 #include "src/bootstrapper.h" | 13 #include "src/bootstrapper.h" |
| 14 #include "src/codegen.h" | 14 #include "src/codegen.h" |
| 15 #include "src/compilation-cache.h" | 15 #include "src/compilation-cache.h" |
| 16 #include "src/compiler/pipeline.h" | 16 #include "src/compiler/pipeline.h" |
| 17 #include "src/crankshaft/hydrogen.h" | 17 #include "src/crankshaft/hydrogen.h" |
| 18 #include "src/debug/debug.h" | 18 #include "src/debug/debug.h" |
| 19 #include "src/debug/liveedit.h" | 19 #include "src/debug/liveedit.h" |
| 20 #include "src/deoptimizer.h" | 20 #include "src/deoptimizer.h" |
| 21 #include "src/frames-inl.h" | 21 #include "src/frames-inl.h" |
| 22 #include "src/full-codegen/full-codegen.h" | 22 #include "src/full-codegen/full-codegen.h" |
| 23 #include "src/interpreter/interpreter.h" | 23 #include "src/interpreter/interpreter.h" |
| 24 #include "src/isolate-inl.h" | 24 #include "src/isolate-inl.h" |
| 25 #include "src/log-inl.h" | 25 #include "src/log-inl.h" |
| 26 #include "src/messages.h" | 26 #include "src/messages.h" |
| 27 #include "src/parsing/parser.h" | 27 #include "src/parsing/parser.h" |
| 28 #include "src/parsing/rewriter.h" | 28 #include "src/parsing/rewriter.h" |
| 29 #include "src/parsing/scanner-character-streams.h" | 29 #include "src/parsing/scanner-character-streams.h" |
| 30 #include "src/profiler/cpu-profiler.h" | |
| 31 #include "src/runtime-profiler.h" | 30 #include "src/runtime-profiler.h" |
| 32 #include "src/snapshot/code-serializer.h" | 31 #include "src/snapshot/code-serializer.h" |
| 33 #include "src/typing-asm.h" | 32 #include "src/typing-asm.h" |
| 34 #include "src/vm-state-inl.h" | 33 #include "src/vm-state-inl.h" |
| 35 | 34 |
| 36 namespace v8 { | 35 namespace v8 { |
| 37 namespace internal { | 36 namespace internal { |
| 38 | 37 |
| 39 | 38 |
| 40 #define PARSE_INFO_GETTER(type, name) \ | 39 #define PARSE_INFO_GETTER(type, name) \ |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 // Local helper methods that make up the compilation pipeline. | 372 // Local helper methods that make up the compilation pipeline. |
| 374 | 373 |
| 375 namespace { | 374 namespace { |
| 376 | 375 |
| 377 bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { | 376 bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { |
| 378 return shared->is_toplevel() && shared->script()->IsScript() && | 377 return shared->is_toplevel() && shared->script()->IsScript() && |
| 379 Script::cast(shared->script())->compilation_type() == | 378 Script::cast(shared->script())->compilation_type() == |
| 380 Script::COMPILATION_TYPE_EVAL; | 379 Script::COMPILATION_TYPE_EVAL; |
| 381 } | 380 } |
| 382 | 381 |
| 383 void RecordFunctionCompilation(Logger::LogEventsAndTags tag, | 382 void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag, |
| 384 CompilationInfo* info) { | 383 CompilationInfo* info) { |
| 385 // Log the code generation. If source information is available include | 384 // Log the code generation. If source information is available include |
| 386 // script name and line number. Check explicitly whether logging is | 385 // script name and line number. Check explicitly whether logging is |
| 387 // enabled as finding the line number is not free. | 386 // enabled as finding the line number is not free. |
| 388 if (info->isolate()->logger()->is_logging_code_events() || | 387 if (info->isolate()->logger()->is_logging_code_events() || |
| 389 info->isolate()->is_profiling()) { | 388 info->isolate()->is_profiling()) { |
| 390 Handle<SharedFunctionInfo> shared = info->shared_info(); | 389 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 391 Handle<Script> script = info->parse_info()->script(); | 390 Handle<Script> script = info->parse_info()->script(); |
| 392 Handle<AbstractCode> abstract_code = | 391 Handle<AbstractCode> abstract_code = |
| 393 info->has_bytecode_array() | 392 info->has_bytecode_array() |
| 394 ? Handle<AbstractCode>::cast(info->bytecode_array()) | 393 ? Handle<AbstractCode>::cast(info->bytecode_array()) |
| 395 : Handle<AbstractCode>::cast(info->code()); | 394 : Handle<AbstractCode>::cast(info->code()); |
| 396 if (abstract_code.is_identical_to( | 395 if (abstract_code.is_identical_to( |
| 397 info->isolate()->builtins()->CompileLazy())) { | 396 info->isolate()->builtins()->CompileLazy())) { |
| 398 return; | 397 return; |
| 399 } | 398 } |
| 400 int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; | 399 int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; |
| 401 int column_num = | 400 int column_num = |
| 402 Script::GetColumnNumber(script, shared->start_position()) + 1; | 401 Script::GetColumnNumber(script, shared->start_position()) + 1; |
| 403 String* script_name = script->name()->IsString() | 402 String* script_name = script->name()->IsString() |
| 404 ? String::cast(script->name()) | 403 ? String::cast(script->name()) |
| 405 : info->isolate()->heap()->empty_string(); | 404 : info->isolate()->heap()->empty_string(); |
| 406 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script); | 405 CodeEventListener::LogEventsAndTags log_tag = |
| 406 Logger::ToNativeByScript(tag, *script); |
| 407 PROFILE(info->isolate(), | 407 PROFILE(info->isolate(), |
| 408 CodeCreateEvent(log_tag, *abstract_code, *shared, script_name, | 408 CodeCreateEvent(log_tag, *abstract_code, *shared, script_name, |
| 409 line_num, column_num)); | 409 line_num, column_num)); |
| 410 } | 410 } |
| 411 } | 411 } |
| 412 | 412 |
| 413 void EnsureFeedbackMetadata(CompilationInfo* info) { | 413 void EnsureFeedbackMetadata(CompilationInfo* info) { |
| 414 DCHECK(info->has_shared_info()); | 414 DCHECK(info->has_shared_info()); |
| 415 | 415 |
| 416 // If no type feedback metadata exists, we create it now. At this point the | 416 // If no type feedback metadata exists, we create it now. At this point the |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 // Compile either unoptimized code or bytecode for the interpreter. | 545 // Compile either unoptimized code or bytecode for the interpreter. |
| 546 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); | 546 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
| 547 | 547 |
| 548 // Update the shared function info with the scope info. | 548 // Update the shared function info with the scope info. |
| 549 InstallSharedScopeInfo(info, shared); | 549 InstallSharedScopeInfo(info, shared); |
| 550 | 550 |
| 551 // Install compilation result on the shared function info | 551 // Install compilation result on the shared function info |
| 552 InstallSharedCompilationResult(info, shared); | 552 InstallSharedCompilationResult(info, shared); |
| 553 | 553 |
| 554 // Record the function compilation event. | 554 // Record the function compilation event. |
| 555 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info); | 555 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
| 556 | 556 |
| 557 return info->code(); | 557 return info->code(); |
| 558 } | 558 } |
| 559 | 559 |
| 560 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( | 560 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( |
| 561 Handle<JSFunction> function, BailoutId osr_ast_id) { | 561 Handle<JSFunction> function, BailoutId osr_ast_id) { |
| 562 Handle<SharedFunctionInfo> shared(function->shared()); | 562 Handle<SharedFunctionInfo> shared(function->shared()); |
| 563 DisallowHeapAllocation no_gc; | 563 DisallowHeapAllocation no_gc; |
| 564 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( | 564 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( |
| 565 function->context()->native_context(), osr_ast_id); | 565 function->context()->native_context(), osr_ast_id); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 info->closure()->ShortPrint(); | 667 info->closure()->ShortPrint(); |
| 668 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); | 668 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
| 669 } | 669 } |
| 670 return false; | 670 return false; |
| 671 } | 671 } |
| 672 | 672 |
| 673 // Success! | 673 // Success! |
| 674 job->RecordOptimizationStats(); | 674 job->RecordOptimizationStats(); |
| 675 DCHECK(!isolate->has_pending_exception()); | 675 DCHECK(!isolate->has_pending_exception()); |
| 676 InsertCodeIntoOptimizedCodeMap(info); | 676 InsertCodeIntoOptimizedCodeMap(info); |
| 677 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info); | 677 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
| 678 return true; | 678 return true; |
| 679 } | 679 } |
| 680 | 680 |
| 681 bool GetOptimizedCodeLater(CompilationJob* job) { | 681 bool GetOptimizedCodeLater(CompilationJob* job) { |
| 682 CompilationInfo* info = job->info(); | 682 CompilationInfo* info = job->info(); |
| 683 Isolate* isolate = info->isolate(); | 683 Isolate* isolate = info->isolate(); |
| 684 | 684 |
| 685 if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) { | 685 if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) { |
| 686 if (FLAG_trace_concurrent_recompilation) { | 686 if (FLAG_trace_concurrent_recompilation) { |
| 687 PrintF(" ** Compilation queue full, will retry optimizing "); | 687 PrintF(" ** Compilation queue full, will retry optimizing "); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 946 // that it can be used as the "source of truth" eventually. | 946 // that it can be used as the "source of truth" eventually. |
| 947 shared->ClearBytecodeArray(); | 947 shared->ClearBytecodeArray(); |
| 948 | 948 |
| 949 // Update the shared function info with the scope info. | 949 // Update the shared function info with the scope info. |
| 950 InstallSharedScopeInfo(&info, shared); | 950 InstallSharedScopeInfo(&info, shared); |
| 951 | 951 |
| 952 // Install compilation result on the shared function info | 952 // Install compilation result on the shared function info |
| 953 InstallSharedCompilationResult(&info, shared); | 953 InstallSharedCompilationResult(&info, shared); |
| 954 | 954 |
| 955 // Record the function compilation event. | 955 // Record the function compilation event. |
| 956 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &info); | 956 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, &info); |
| 957 | 957 |
| 958 return info.code(); | 958 return info.code(); |
| 959 } | 959 } |
| 960 | 960 |
| 961 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { | 961 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { |
| 962 Isolate* isolate = function->GetIsolate(); | 962 Isolate* isolate = function->GetIsolate(); |
| 963 DCHECK(!isolate->has_pending_exception()); | 963 DCHECK(!isolate->has_pending_exception()); |
| 964 DCHECK(!function->is_compiled()); | 964 DCHECK(!function->is_compiled()); |
| 965 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); | 965 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); |
| 966 TRACE_EVENT0("v8", "V8.CompileCode"); | 966 TRACE_EVENT0("v8", "V8.CompileCode"); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 // Update the shared function info with the scope info. | 1104 // Update the shared function info with the scope info. |
| 1105 InstallSharedScopeInfo(info, result); | 1105 InstallSharedScopeInfo(info, result); |
| 1106 | 1106 |
| 1107 // Install compilation result on the shared function info | 1107 // Install compilation result on the shared function info |
| 1108 InstallSharedCompilationResult(info, result); | 1108 InstallSharedCompilationResult(info, result); |
| 1109 | 1109 |
| 1110 Handle<String> script_name = | 1110 Handle<String> script_name = |
| 1111 script->name()->IsString() | 1111 script->name()->IsString() |
| 1112 ? Handle<String>(String::cast(script->name())) | 1112 ? Handle<String>(String::cast(script->name())) |
| 1113 : isolate->factory()->empty_string(); | 1113 : isolate->factory()->empty_string(); |
| 1114 Logger::LogEventsAndTags log_tag = | 1114 CodeEventListener::LogEventsAndTags log_tag = |
| 1115 parse_info->is_eval() | 1115 parse_info->is_eval() |
| 1116 ? Logger::EVAL_TAG | 1116 ? CodeEventListener::EVAL_TAG |
| 1117 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script); | 1117 : Logger::ToNativeByScript(CodeEventListener::SCRIPT_TAG, *script); |
| 1118 | 1118 |
| 1119 PROFILE(isolate, CodeCreateEvent(log_tag, result->abstract_code(), *result, | 1119 PROFILE(isolate, CodeCreateEvent(log_tag, result->abstract_code(), *result, |
| 1120 *script_name)); | 1120 *script_name)); |
| 1121 | 1121 |
| 1122 if (!script.is_null()) | 1122 if (!script.is_null()) |
| 1123 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED); | 1123 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED); |
| 1124 } | 1124 } |
| 1125 | 1125 |
| 1126 return result; | 1126 return result; |
| 1127 } | 1127 } |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1365 // The scope info might not have been set if a lazily compiled | 1365 // The scope info might not have been set if a lazily compiled |
| 1366 // function is inlined before being called for the first time. | 1366 // function is inlined before being called for the first time. |
| 1367 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { | 1367 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { |
| 1368 InstallSharedScopeInfo(info, shared); | 1368 InstallSharedScopeInfo(info, shared); |
| 1369 } | 1369 } |
| 1370 | 1370 |
| 1371 // Install compilation result on the shared function info | 1371 // Install compilation result on the shared function info |
| 1372 shared->EnableDeoptimizationSupport(*unoptimized.code()); | 1372 shared->EnableDeoptimizationSupport(*unoptimized.code()); |
| 1373 | 1373 |
| 1374 // The existing unoptimized code was replaced with the new one. | 1374 // The existing unoptimized code was replaced with the new one. |
| 1375 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized); | 1375 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, |
| 1376 &unoptimized); |
| 1376 } | 1377 } |
| 1377 return true; | 1378 return true; |
| 1378 } | 1379 } |
| 1379 | 1380 |
| 1380 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( | 1381 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( |
| 1381 Handle<String> source, Handle<SharedFunctionInfo> outer_info, | 1382 Handle<String> source, Handle<SharedFunctionInfo> outer_info, |
| 1382 Handle<Context> context, LanguageMode language_mode, | 1383 Handle<Context> context, LanguageMode language_mode, |
| 1383 ParseRestriction restriction, int eval_scope_position, int eval_position, | 1384 ParseRestriction restriction, int eval_scope_position, int eval_position, |
| 1384 int line_offset, int column_offset, Handle<Object> script_name, | 1385 int line_offset, int column_offset, Handle<Object> script_name, |
| 1385 ScriptOriginOptions options) { | 1386 ScriptOriginOptions options) { |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1681 } | 1682 } |
| 1682 // Update the shared function info with the scope info. | 1683 // Update the shared function info with the scope info. |
| 1683 InstallSharedScopeInfo(&info, result); | 1684 InstallSharedScopeInfo(&info, result); |
| 1684 // Install compilation result on the shared function info. | 1685 // Install compilation result on the shared function info. |
| 1685 InstallSharedCompilationResult(&info, result); | 1686 InstallSharedCompilationResult(&info, result); |
| 1686 } else { | 1687 } else { |
| 1687 return Handle<SharedFunctionInfo>::null(); | 1688 return Handle<SharedFunctionInfo>::null(); |
| 1688 } | 1689 } |
| 1689 | 1690 |
| 1690 if (maybe_existing.is_null()) { | 1691 if (maybe_existing.is_null()) { |
| 1691 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info); | 1692 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info); |
| 1692 } | 1693 } |
| 1693 | 1694 |
| 1694 return result; | 1695 return result; |
| 1695 } | 1696 } |
| 1696 | 1697 |
| 1697 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( | 1698 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( |
| 1698 v8::Extension* extension, Handle<String> name) { | 1699 v8::Extension* extension, Handle<String> name) { |
| 1699 Isolate* isolate = name->GetIsolate(); | 1700 Isolate* isolate = name->GetIsolate(); |
| 1700 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); | 1701 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); |
| 1701 | 1702 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1753 // Except when OSR already disabled optimization for some reason. | 1754 // Except when OSR already disabled optimization for some reason. |
| 1754 // 3) The code may have already been invalidated due to dependency change. | 1755 // 3) The code may have already been invalidated due to dependency change. |
| 1755 // 4) Code generation may have failed. | 1756 // 4) Code generation may have failed. |
| 1756 if (job->last_status() == CompilationJob::SUCCEEDED) { | 1757 if (job->last_status() == CompilationJob::SUCCEEDED) { |
| 1757 if (shared->optimization_disabled()) { | 1758 if (shared->optimization_disabled()) { |
| 1758 job->RetryOptimization(kOptimizationDisabled); | 1759 job->RetryOptimization(kOptimizationDisabled); |
| 1759 } else if (info->dependencies()->HasAborted()) { | 1760 } else if (info->dependencies()->HasAborted()) { |
| 1760 job->RetryOptimization(kBailedOutDueToDependencyChange); | 1761 job->RetryOptimization(kBailedOutDueToDependencyChange); |
| 1761 } else if (job->GenerateCode() == CompilationJob::SUCCEEDED) { | 1762 } else if (job->GenerateCode() == CompilationJob::SUCCEEDED) { |
| 1762 job->RecordOptimizationStats(); | 1763 job->RecordOptimizationStats(); |
| 1763 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info); | 1764 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
| 1764 if (shared->SearchOptimizedCodeMap(info->context()->native_context(), | 1765 if (shared->SearchOptimizedCodeMap(info->context()->native_context(), |
| 1765 info->osr_ast_id()).code == nullptr) { | 1766 info->osr_ast_id()).code == nullptr) { |
| 1766 InsertCodeIntoOptimizedCodeMap(info); | 1767 InsertCodeIntoOptimizedCodeMap(info); |
| 1767 } | 1768 } |
| 1768 if (FLAG_trace_opt) { | 1769 if (FLAG_trace_opt) { |
| 1769 PrintF("[completed optimizing "); | 1770 PrintF("[completed optimizing "); |
| 1770 info->closure()->ShortPrint(); | 1771 info->closure()->ShortPrint(); |
| 1771 PrintF("]\n"); | 1772 PrintF("]\n"); |
| 1772 } | 1773 } |
| 1773 info->closure()->ReplaceCode(*info->code()); | 1774 info->closure()->ReplaceCode(*info->code()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1805 DCHECK(shared->is_compiled()); | 1806 DCHECK(shared->is_compiled()); |
| 1806 function->set_literals(cached.literals); | 1807 function->set_literals(cached.literals); |
| 1807 } else if (shared->is_compiled()) { | 1808 } else if (shared->is_compiled()) { |
| 1808 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1809 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
| 1809 JSFunction::EnsureLiterals(function); | 1810 JSFunction::EnsureLiterals(function); |
| 1810 } | 1811 } |
| 1811 } | 1812 } |
| 1812 | 1813 |
| 1813 } // namespace internal | 1814 } // namespace internal |
| 1814 } // namespace v8 | 1815 } // namespace v8 |
| OLD | NEW |