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