| 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 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "src/asmjs/asm-js.h" | 10 #include "src/asmjs/asm-js.h" |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 DCHECK_NOT_NULL(info->scope()); | 353 DCHECK_NOT_NULL(info->scope()); |
| 354 | 354 |
| 355 EnsureFeedbackMetadata(info); | 355 EnsureFeedbackMetadata(info); |
| 356 if (ShouldUseIgnition(info)) { | 356 if (ShouldUseIgnition(info)) { |
| 357 return interpreter::Interpreter::NewCompilationJob(info); | 357 return interpreter::Interpreter::NewCompilationJob(info); |
| 358 } else { | 358 } else { |
| 359 return FullCodeGenerator::NewCompilationJob(info); | 359 return FullCodeGenerator::NewCompilationJob(info); |
| 360 } | 360 } |
| 361 } | 361 } |
| 362 | 362 |
| 363 bool GenerateUnoptimizedCode(CompilationInfo* info) { | |
| 364 if (FLAG_validate_asm && info->scope()->asm_module() && | |
| 365 !info->shared_info()->is_asm_wasm_broken()) { | |
| 366 EnsureFeedbackMetadata(info); | |
| 367 MaybeHandle<FixedArray> wasm_data; | |
| 368 wasm_data = AsmJs::ConvertAsmToWasm(info->parse_info()); | |
| 369 if (!wasm_data.is_null()) { | |
| 370 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); | |
| 371 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); | |
| 372 return true; | |
| 373 } | |
| 374 } | |
| 375 | |
| 376 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); | |
| 377 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; | |
| 378 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; | |
| 379 if (job->FinalizeJob() != CompilationJob::SUCCEEDED) return false; | |
| 380 job->RecordUnoptimizedCompilationStats(); | |
| 381 return true; | |
| 382 } | |
| 383 | |
| 384 bool CompileUnoptimizedCode(CompilationInfo* info) { | |
| 385 DCHECK(AllowCompilation::IsAllowed(info->isolate())); | |
| 386 if (!Compiler::Analyze(info->parse_info()) || | |
| 387 !GenerateUnoptimizedCode(info)) { | |
| 388 Isolate* isolate = info->isolate(); | |
| 389 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | |
| 390 return false; | |
| 391 } | |
| 392 return true; | |
| 393 } | |
| 394 | |
| 395 void InstallSharedScopeInfo(CompilationInfo* info, | 363 void InstallSharedScopeInfo(CompilationInfo* info, |
| 396 Handle<SharedFunctionInfo> shared) { | 364 Handle<SharedFunctionInfo> shared) { |
| 397 Handle<ScopeInfo> scope_info = info->scope()->scope_info(); | 365 Handle<ScopeInfo> scope_info = info->scope()->scope_info(); |
| 398 shared->set_scope_info(*scope_info); | 366 shared->set_scope_info(*scope_info); |
| 399 Scope* outer_scope = info->scope()->GetOuterScopeWithContext(); | 367 Scope* outer_scope = info->scope()->GetOuterScopeWithContext(); |
| 400 if (outer_scope) { | 368 if (outer_scope) { |
| 401 shared->set_outer_scope_info(*outer_scope->scope_info()); | 369 shared->set_outer_scope_info(*outer_scope->scope_info()); |
| 402 } | 370 } |
| 403 } | 371 } |
| 404 | 372 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 419 } | 387 } |
| 420 | 388 |
| 421 void InstallUnoptimizedCode(CompilationInfo* info) { | 389 void InstallUnoptimizedCode(CompilationInfo* info) { |
| 422 Handle<SharedFunctionInfo> shared = info->shared_info(); | 390 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 423 | 391 |
| 424 // Update the shared function info with the scope info. | 392 // Update the shared function info with the scope info. |
| 425 InstallSharedScopeInfo(info, shared); | 393 InstallSharedScopeInfo(info, shared); |
| 426 | 394 |
| 427 // Install compilation result on the shared function info | 395 // Install compilation result on the shared function info |
| 428 InstallSharedCompilationResult(info, shared); | 396 InstallSharedCompilationResult(info, shared); |
| 397 } |
| 429 | 398 |
| 430 // Record the function compilation event. | 399 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { |
| 431 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); | 400 CompilationJob::Status status = job->FinalizeJob(); |
| 401 if (status == CompilationJob::SUCCEEDED) { |
| 402 InstallUnoptimizedCode(job->info()); |
| 403 job->RecordUnoptimizedCompilationStats(); |
| 404 } |
| 405 return status; |
| 406 } |
| 407 |
| 408 bool GenerateUnoptimizedCode(CompilationInfo* info) { |
| 409 if (FLAG_validate_asm && info->scope()->asm_module() && |
| 410 !info->shared_info()->is_asm_wasm_broken()) { |
| 411 EnsureFeedbackMetadata(info); |
| 412 MaybeHandle<FixedArray> wasm_data; |
| 413 wasm_data = AsmJs::ConvertAsmToWasm(info->parse_info()); |
| 414 if (!wasm_data.is_null()) { |
| 415 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); |
| 416 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); |
| 417 InstallUnoptimizedCode(info); |
| 418 return true; |
| 419 } |
| 420 } |
| 421 |
| 422 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); |
| 423 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; |
| 424 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; |
| 425 if (FinalizeUnoptimizedCompilationJob(job.get()) != |
| 426 CompilationJob::SUCCEEDED) { |
| 427 return false; |
| 428 } |
| 429 return true; |
| 430 } |
| 431 |
| 432 bool CompileUnoptimizedCode(CompilationInfo* info) { |
| 433 DCHECK(AllowCompilation::IsAllowed(info->isolate())); |
| 434 if (!Compiler::Analyze(info->parse_info()) || |
| 435 !GenerateUnoptimizedCode(info)) { |
| 436 Isolate* isolate = info->isolate(); |
| 437 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
| 438 return false; |
| 439 } |
| 440 return true; |
| 432 } | 441 } |
| 433 | 442 |
| 434 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { | 443 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { |
| 435 VMState<COMPILER> state(info->isolate()); | 444 VMState<COMPILER> state(info->isolate()); |
| 436 PostponeInterruptsScope postpone(info->isolate()); | 445 PostponeInterruptsScope postpone(info->isolate()); |
| 437 | 446 |
| 438 // Parse and update CompilationInfo with the results. | 447 // Parse and update CompilationInfo with the results. |
| 439 if (!Parse(info->parse_info())) return MaybeHandle<Code>(); | 448 if (!Parse(info->parse_info())) return MaybeHandle<Code>(); |
| 440 DCHECK_EQ(info->shared_info()->language_mode(), | 449 DCHECK_EQ(info->shared_info()->language_mode(), |
| 441 info->literal()->language_mode()); | 450 info->literal()->language_mode()); |
| 442 | 451 |
| 443 // Compile either unoptimized code or bytecode for the interpreter. | 452 // Compile either unoptimized code or bytecode for the interpreter. |
| 444 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); | 453 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
| 445 | 454 |
| 446 InstallUnoptimizedCode(info); | 455 // Record the function compilation event. |
| 456 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
| 447 | 457 |
| 448 return info->code(); | 458 return info->code(); |
| 449 } | 459 } |
| 450 | 460 |
| 451 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { | |
| 452 CompilationJob::Status status = job->FinalizeJob(); | |
| 453 if (status == CompilationJob::SUCCEEDED) { | |
| 454 DCHECK(!job->info()->shared_info()->is_compiled()); | |
| 455 InstallUnoptimizedCode(job->info()); | |
| 456 job->RecordUnoptimizedCompilationStats(); | |
| 457 } | |
| 458 return status; | |
| 459 } | |
| 460 | |
| 461 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( | 461 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( |
| 462 Handle<JSFunction> function, BailoutId osr_ast_id) { | 462 Handle<JSFunction> function, BailoutId osr_ast_id) { |
| 463 Handle<SharedFunctionInfo> shared(function->shared()); | 463 Handle<SharedFunctionInfo> shared(function->shared()); |
| 464 DisallowHeapAllocation no_gc; | 464 DisallowHeapAllocation no_gc; |
| 465 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( | 465 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( |
| 466 function->context()->native_context(), osr_ast_id); | 466 function->context()->native_context(), osr_ast_id); |
| 467 if (cached.code != nullptr) { | 467 if (cached.code != nullptr) { |
| 468 // Caching of optimized code enabled and optimized code found. | 468 // Caching of optimized code enabled and optimized code found. |
| 469 if (cached.literals != nullptr) function->set_literals(cached.literals); | 469 if (cached.literals != nullptr) function->set_literals(cached.literals); |
| 470 DCHECK(!cached.code->marked_for_deoptimization()); | 470 DCHECK(!cached.code->marked_for_deoptimization()); |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1106 DCHECK_EQ(kNoSourcePosition, lit->function_token_position()); | 1106 DCHECK_EQ(kNoSourcePosition, lit->function_token_position()); |
| 1107 result = NewSharedFunctionInfoForLiteral(isolate, lit, script); | 1107 result = NewSharedFunctionInfoForLiteral(isolate, lit, script); |
| 1108 result->set_is_toplevel(true); | 1108 result->set_is_toplevel(true); |
| 1109 parse_info->set_shared_info(result); | 1109 parse_info->set_shared_info(result); |
| 1110 | 1110 |
| 1111 // Compile the code. | 1111 // Compile the code. |
| 1112 if (!CompileUnoptimizedCode(info)) { | 1112 if (!CompileUnoptimizedCode(info)) { |
| 1113 return Handle<SharedFunctionInfo>::null(); | 1113 return Handle<SharedFunctionInfo>::null(); |
| 1114 } | 1114 } |
| 1115 | 1115 |
| 1116 // Update the shared function info with the scope info. | |
| 1117 InstallSharedScopeInfo(info, result); | |
| 1118 | |
| 1119 // Install compilation result on the shared function info | |
| 1120 InstallSharedCompilationResult(info, result); | |
| 1121 | |
| 1122 Handle<String> script_name = | 1116 Handle<String> script_name = |
| 1123 script->name()->IsString() | 1117 script->name()->IsString() |
| 1124 ? Handle<String>(String::cast(script->name())) | 1118 ? Handle<String>(String::cast(script->name())) |
| 1125 : isolate->factory()->empty_string(); | 1119 : isolate->factory()->empty_string(); |
| 1126 CodeEventListener::LogEventsAndTags log_tag = | 1120 CodeEventListener::LogEventsAndTags log_tag = |
| 1127 parse_info->is_eval() | 1121 parse_info->is_eval() |
| 1128 ? CodeEventListener::EVAL_TAG | 1122 ? CodeEventListener::EVAL_TAG |
| 1129 : Logger::ToNativeByScript(CodeEventListener::SCRIPT_TAG, *script); | 1123 : Logger::ToNativeByScript(CodeEventListener::SCRIPT_TAG, *script); |
| 1130 | 1124 |
| 1131 PROFILE(isolate, CodeCreateEvent(log_tag, result->abstract_code(), *result, | 1125 PROFILE(isolate, CodeCreateEvent(log_tag, result->abstract_code(), *result, |
| (...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1769 if (outer_scope) { | 1763 if (outer_scope) { |
| 1770 result->set_outer_scope_info(*outer_scope->scope_info()); | 1764 result->set_outer_scope_info(*outer_scope->scope_info()); |
| 1771 } | 1765 } |
| 1772 } else if (Renumber(info.parse_info()) && GenerateUnoptimizedCode(&info)) { | 1766 } else if (Renumber(info.parse_info()) && GenerateUnoptimizedCode(&info)) { |
| 1773 // Code generation will ensure that the feedback vector is present and | 1767 // Code generation will ensure that the feedback vector is present and |
| 1774 // appropriately sized. | 1768 // appropriately sized. |
| 1775 DCHECK(!info.code().is_null()); | 1769 DCHECK(!info.code().is_null()); |
| 1776 if (literal->should_be_used_once_hint()) { | 1770 if (literal->should_be_used_once_hint()) { |
| 1777 info.code()->MarkToBeExecutedOnce(isolate); | 1771 info.code()->MarkToBeExecutedOnce(isolate); |
| 1778 } | 1772 } |
| 1779 // Update the shared function info with the scope info. | |
| 1780 InstallSharedScopeInfo(&info, result); | |
| 1781 // Install compilation result on the shared function info. | |
| 1782 InstallSharedCompilationResult(&info, result); | |
| 1783 } else { | 1773 } else { |
| 1784 return Handle<SharedFunctionInfo>::null(); | 1774 return Handle<SharedFunctionInfo>::null(); |
| 1785 } | 1775 } |
| 1786 | 1776 |
| 1787 if (maybe_existing.is_null()) { | 1777 if (maybe_existing.is_null()) { |
| 1788 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info); | 1778 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info); |
| 1789 } | 1779 } |
| 1790 | 1780 |
| 1791 return result; | 1781 return result; |
| 1792 } | 1782 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1843 | 1833 |
| 1844 bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { | 1834 bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { |
| 1845 // Take ownership of compilation job. Deleting job also tears down the zone. | 1835 // Take ownership of compilation job. Deleting job also tears down the zone. |
| 1846 std::unique_ptr<CompilationJob> job(raw_job); | 1836 std::unique_ptr<CompilationJob> job(raw_job); |
| 1847 | 1837 |
| 1848 VMState<COMPILER> state(job->info()->isolate()); | 1838 VMState<COMPILER> state(job->info()->isolate()); |
| 1849 if (job->info()->IsOptimizing()) { | 1839 if (job->info()->IsOptimizing()) { |
| 1850 return FinalizeOptimizedCompilationJob(job.get()) == | 1840 return FinalizeOptimizedCompilationJob(job.get()) == |
| 1851 CompilationJob::SUCCEEDED; | 1841 CompilationJob::SUCCEEDED; |
| 1852 } else { | 1842 } else { |
| 1853 return FinalizeUnoptimizedCompilationJob(job.get()) == | 1843 if (FinalizeUnoptimizedCompilationJob(job.get()) == |
| 1854 CompilationJob::SUCCEEDED; | 1844 CompilationJob::SUCCEEDED) { |
| 1845 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, |
| 1846 job->info()); |
| 1847 return true; |
| 1848 } |
| 1849 return false; |
| 1855 } | 1850 } |
| 1856 } | 1851 } |
| 1857 | 1852 |
| 1858 void Compiler::PostInstantiation(Handle<JSFunction> function, | 1853 void Compiler::PostInstantiation(Handle<JSFunction> function, |
| 1859 PretenureFlag pretenure) { | 1854 PretenureFlag pretenure) { |
| 1860 Handle<SharedFunctionInfo> shared(function->shared()); | 1855 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1861 | 1856 |
| 1862 if (FLAG_always_opt && shared->allows_lazy_compilation()) { | 1857 if (FLAG_always_opt && shared->allows_lazy_compilation()) { |
| 1863 function->MarkForOptimization(); | 1858 function->MarkForOptimization(); |
| 1864 } | 1859 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1876 DCHECK(shared->is_compiled()); | 1871 DCHECK(shared->is_compiled()); |
| 1877 function->set_literals(cached.literals); | 1872 function->set_literals(cached.literals); |
| 1878 } else if (shared->is_compiled()) { | 1873 } else if (shared->is_compiled()) { |
| 1879 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1874 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
| 1880 JSFunction::EnsureLiterals(function); | 1875 JSFunction::EnsureLiterals(function); |
| 1881 } | 1876 } |
| 1882 } | 1877 } |
| 1883 | 1878 |
| 1884 } // namespace internal | 1879 } // namespace internal |
| 1885 } // namespace v8 | 1880 } // namespace v8 |
| OLD | NEW |