Chromium Code Reviews| 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 19 matching lines...) Expand all Loading... | |
| 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); |
| 429 | 397 |
| 430 // Record the function compilation event. | 398 // Record the function compilation event. |
| 431 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); | 399 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
| 432 } | 400 } |
| 433 | 401 |
| 402 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { | |
| 403 CompilationJob::Status status = job->FinalizeJob(); | |
| 404 if (status == CompilationJob::SUCCEEDED) { | |
| 405 InstallUnoptimizedCode(job->info()); | |
| 406 job->RecordUnoptimizedCompilationStats(); | |
| 407 } | |
| 408 return status; | |
| 409 } | |
| 410 | |
| 411 bool GenerateUnoptimizedCode(CompilationInfo* info) { | |
| 412 if (FLAG_validate_asm && info->scope()->asm_module() && | |
| 413 !info->shared_info()->is_asm_wasm_broken()) { | |
| 414 EnsureFeedbackMetadata(info); | |
| 415 MaybeHandle<FixedArray> wasm_data; | |
| 416 wasm_data = AsmJs::ConvertAsmToWasm(info->parse_info()); | |
| 417 if (!wasm_data.is_null()) { | |
| 418 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); | |
| 419 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); | |
| 420 InstallUnoptimizedCode(info); | |
| 421 return true; | |
| 422 } | |
| 423 } | |
| 424 | |
| 425 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); | |
| 426 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; | |
| 427 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; | |
| 428 if (FinalizeUnoptimizedCompilationJob(job.get()) != | |
| 429 CompilationJob::SUCCEEDED) { | |
| 430 return false; | |
| 431 } | |
| 432 return true; | |
| 433 } | |
| 434 | |
| 435 bool CompileUnoptimizedCode(CompilationInfo* info) { | |
| 436 DCHECK(AllowCompilation::IsAllowed(info->isolate())); | |
| 437 if (!Compiler::Analyze(info->parse_info()) || | |
| 438 !GenerateUnoptimizedCode(info)) { | |
| 439 Isolate* isolate = info->isolate(); | |
| 440 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | |
| 441 return false; | |
| 442 } | |
| 443 return true; | |
| 444 } | |
| 445 | |
| 434 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { | 446 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { |
| 435 VMState<COMPILER> state(info->isolate()); | 447 VMState<COMPILER> state(info->isolate()); |
| 436 PostponeInterruptsScope postpone(info->isolate()); | 448 PostponeInterruptsScope postpone(info->isolate()); |
| 437 | 449 |
| 438 // Parse and update CompilationInfo with the results. | 450 // Parse and update CompilationInfo with the results. |
| 439 if (!Parse(info->parse_info())) return MaybeHandle<Code>(); | 451 if (!Parse(info->parse_info())) return MaybeHandle<Code>(); |
| 440 DCHECK_EQ(info->shared_info()->language_mode(), | 452 DCHECK_EQ(info->shared_info()->language_mode(), |
| 441 info->literal()->language_mode()); | 453 info->literal()->language_mode()); |
| 442 | 454 |
| 443 // Compile either unoptimized code or bytecode for the interpreter. | 455 // Compile either unoptimized code or bytecode for the interpreter. |
| 444 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); | 456 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
| 445 | 457 |
| 446 InstallUnoptimizedCode(info); | |
| 447 | |
| 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, |
|
Michael Starzinger
2016/10/07 16:18:41
This seems to be firing multiple code creation eve
| |
| 1132 *script_name)); | 1126 *script_name)); |
| 1133 | 1127 |
| 1134 if (!script.is_null()) | 1128 if (!script.is_null()) |
| 1135 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED); | 1129 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED); |
| 1136 } | 1130 } |
| 1137 | 1131 |
| 1138 return result; | 1132 return result; |
| 1139 } | 1133 } |
| 1140 | 1134 |
| 1141 } // namespace | 1135 } // namespace |
| (...skipping 627 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); |
|
Michael Starzinger
2016/10/07 16:18:41
Likewise, multiple code creation events firing.
| |
| 1789 } | 1779 } |
| 1790 | 1780 |
| 1791 return result; | 1781 return result; |
| 1792 } | 1782 } |
| 1793 | 1783 |
| 1794 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( | 1784 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( |
| 1795 v8::Extension* extension, Handle<String> name) { | 1785 v8::Extension* extension, Handle<String> name) { |
| 1796 Isolate* isolate = name->GetIsolate(); | 1786 Isolate* isolate = name->GetIsolate(); |
| 1797 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); | 1787 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); |
| 1798 | 1788 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1876 DCHECK(shared->is_compiled()); | 1866 DCHECK(shared->is_compiled()); |
| 1877 function->set_literals(cached.literals); | 1867 function->set_literals(cached.literals); |
| 1878 } else if (shared->is_compiled()) { | 1868 } else if (shared->is_compiled()) { |
| 1879 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1869 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
| 1880 JSFunction::EnsureLiterals(function); | 1870 JSFunction::EnsureLiterals(function); |
| 1881 } | 1871 } |
| 1882 } | 1872 } |
| 1883 | 1873 |
| 1884 } // namespace internal | 1874 } // namespace internal |
| 1885 } // namespace v8 | 1875 } // namespace v8 |
| OLD | NEW |