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 |