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 |