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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 DisallowCodeDependencyChange no_dependency_change; | 275 DisallowCodeDependencyChange no_dependency_change; |
276 DisallowJavascriptExecution no_js(isolate()); | 276 DisallowJavascriptExecution no_js(isolate()); |
277 DCHECK(!info()->dependencies()->HasAborted()); | 277 DCHECK(!info()->dependencies()->HasAborted()); |
278 | 278 |
279 // Delegate to the underlying implementation. | 279 // Delegate to the underlying implementation. |
280 DCHECK(state() == State::kReadyToFinalize); | 280 DCHECK(state() == State::kReadyToFinalize); |
281 ScopedTimer t(&time_taken_to_finalize_); | 281 ScopedTimer t(&time_taken_to_finalize_); |
282 return UpdateState(FinalizeJobImpl(), State::kSucceeded); | 282 return UpdateState(FinalizeJobImpl(), State::kSucceeded); |
283 } | 283 } |
284 | 284 |
| 285 void CompilationJob::RecordUnoptimizedCompilationStats() const { |
| 286 DCHECK(!info()->IsOptimizing()); |
| 287 |
| 288 int code_size; |
| 289 if (info()->has_bytecode_array()) { |
| 290 code_size = info()->bytecode_array()->SizeIncludingMetadata(); |
| 291 } else { |
| 292 code_size = info()->code()->SizeIncludingMetadata(); |
| 293 } |
| 294 |
| 295 Counters* counters = isolate()->counters(); |
| 296 // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually. |
| 297 counters->total_baseline_code_size()->Increment(code_size); |
| 298 counters->total_baseline_compile_count()->Increment(1); |
| 299 |
| 300 // TODO(5203): Add timers for each phase of compilation. |
| 301 } |
| 302 |
| 303 void CompilationJob::RecordOptimizedCompilationStats() const { |
| 304 DCHECK(info()->IsOptimizing()); |
| 305 Handle<JSFunction> function = info()->closure(); |
| 306 if (!function->IsOptimized()) { |
| 307 // Concurrent recompilation and OSR may race. Increment only once. |
| 308 int opt_count = function->shared()->opt_count(); |
| 309 function->shared()->set_opt_count(opt_count + 1); |
| 310 } |
| 311 double ms_creategraph = time_taken_to_prepare_.InMillisecondsF(); |
| 312 double ms_optimize = time_taken_to_execute_.InMillisecondsF(); |
| 313 double ms_codegen = time_taken_to_finalize_.InMillisecondsF(); |
| 314 if (FLAG_trace_opt) { |
| 315 PrintF("[optimizing "); |
| 316 function->ShortPrint(); |
| 317 PrintF(" - took %0.3f, %0.3f, %0.3f ms]\n", ms_creategraph, ms_optimize, |
| 318 ms_codegen); |
| 319 } |
| 320 if (FLAG_trace_opt_stats) { |
| 321 static double compilation_time = 0.0; |
| 322 static int compiled_functions = 0; |
| 323 static int code_size = 0; |
| 324 |
| 325 compilation_time += (ms_creategraph + ms_optimize + ms_codegen); |
| 326 compiled_functions++; |
| 327 code_size += function->shared()->SourceSize(); |
| 328 PrintF("Compiled: %d functions with %d byte source size in %fms.\n", |
| 329 compiled_functions, code_size, compilation_time); |
| 330 } |
| 331 if (FLAG_hydrogen_stats) { |
| 332 isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_prepare_, |
| 333 time_taken_to_execute_, |
| 334 time_taken_to_finalize_); |
| 335 } |
| 336 } |
| 337 |
285 namespace { | 338 namespace { |
286 | 339 |
287 void AddWeakObjectToCodeDependency(Isolate* isolate, Handle<HeapObject> object, | 340 void AddWeakObjectToCodeDependency(Isolate* isolate, Handle<HeapObject> object, |
288 Handle<Code> code) { | 341 Handle<Code> code) { |
289 Handle<WeakCell> cell = Code::WeakCellFor(code); | 342 Handle<WeakCell> cell = Code::WeakCellFor(code); |
290 Heap* heap = isolate->heap(); | 343 Heap* heap = isolate->heap(); |
291 if (heap->InNewSpace(*object)) { | 344 if (heap->InNewSpace(*object)) { |
292 heap->AddWeakNewSpaceObjectToCodeDependency(object, cell); | 345 heap->AddWeakNewSpaceObjectToCodeDependency(object, cell); |
293 } else { | 346 } else { |
294 Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object)); | 347 Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object)); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 isolate->heap()->AddRetainedMap(map); | 386 isolate->heap()->AddRetainedMap(map); |
334 } | 387 } |
335 Map::AddDependentCode(map, DependentCode::kWeakCodeGroup, code); | 388 Map::AddDependentCode(map, DependentCode::kWeakCodeGroup, code); |
336 } | 389 } |
337 for (Handle<HeapObject> object : objects) { | 390 for (Handle<HeapObject> object : objects) { |
338 AddWeakObjectToCodeDependency(isolate, object, code); | 391 AddWeakObjectToCodeDependency(isolate, object, code); |
339 } | 392 } |
340 code->set_can_have_weak_objects(true); | 393 code->set_can_have_weak_objects(true); |
341 } | 394 } |
342 | 395 |
343 void CompilationJob::RecordOptimizationStats() { | |
344 DCHECK(info()->IsOptimizing()); | |
345 Handle<JSFunction> function = info()->closure(); | |
346 if (!function->IsOptimized()) { | |
347 // Concurrent recompilation and OSR may race. Increment only once. | |
348 int opt_count = function->shared()->opt_count(); | |
349 function->shared()->set_opt_count(opt_count + 1); | |
350 } | |
351 double ms_creategraph = time_taken_to_prepare_.InMillisecondsF(); | |
352 double ms_optimize = time_taken_to_execute_.InMillisecondsF(); | |
353 double ms_codegen = time_taken_to_finalize_.InMillisecondsF(); | |
354 if (FLAG_trace_opt) { | |
355 PrintF("[optimizing "); | |
356 function->ShortPrint(); | |
357 PrintF(" - took %0.3f, %0.3f, %0.3f ms]\n", ms_creategraph, ms_optimize, | |
358 ms_codegen); | |
359 } | |
360 if (FLAG_trace_opt_stats) { | |
361 static double compilation_time = 0.0; | |
362 static int compiled_functions = 0; | |
363 static int code_size = 0; | |
364 | |
365 compilation_time += (ms_creategraph + ms_optimize + ms_codegen); | |
366 compiled_functions++; | |
367 code_size += function->shared()->SourceSize(); | |
368 PrintF("Compiled: %d functions with %d byte source size in %fms.\n", | |
369 compiled_functions, code_size, compilation_time); | |
370 } | |
371 if (FLAG_hydrogen_stats) { | |
372 isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_prepare_, | |
373 time_taken_to_execute_, | |
374 time_taken_to_finalize_); | |
375 } | |
376 } | |
377 | |
378 // ---------------------------------------------------------------------------- | 396 // ---------------------------------------------------------------------------- |
379 // Local helper methods that make up the compilation pipeline. | 397 // Local helper methods that make up the compilation pipeline. |
380 | 398 |
381 namespace { | 399 namespace { |
382 | 400 |
383 bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { | 401 bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { |
384 return shared->is_toplevel() && shared->script()->IsScript() && | 402 return shared->is_toplevel() && shared->script()->IsScript() && |
385 Script::cast(shared->script())->compilation_type() == | 403 Script::cast(shared->script())->compilation_type() == |
386 Script::COMPILATION_TYPE_EVAL; | 404 Script::COMPILATION_TYPE_EVAL; |
387 } | 405 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 // Checks whether top level functions should be passed by the filter. | 476 // Checks whether top level functions should be passed by the filter. |
459 if (info->shared_info()->is_toplevel()) { | 477 if (info->shared_info()->is_toplevel()) { |
460 Vector<const char> filter = CStrVector(FLAG_ignition_filter); | 478 Vector<const char> filter = CStrVector(FLAG_ignition_filter); |
461 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); | 479 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); |
462 } | 480 } |
463 | 481 |
464 // Finally respect the filter. | 482 // Finally respect the filter. |
465 return info->shared_info()->PassesFilter(FLAG_ignition_filter); | 483 return info->shared_info()->PassesFilter(FLAG_ignition_filter); |
466 } | 484 } |
467 | 485 |
468 int CodeAndMetadataSize(CompilationInfo* info) { | 486 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { |
469 if (info->has_bytecode_array()) { | 487 // Function should have been parsed and analyzed before creating a compilation |
470 return info->bytecode_array()->SizeIncludingMetadata(); | 488 // job. |
| 489 DCHECK_NOT_NULL(info->literal()); |
| 490 DCHECK_NOT_NULL(info->scope()); |
| 491 DCHECK(!(FLAG_validate_asm && info->scope()->asm_module())); |
| 492 |
| 493 EnsureFeedbackMetadata(info); |
| 494 |
| 495 if (ShouldUseIgnition(info)) { |
| 496 return interpreter::Interpreter::NewCompilationJob(info); |
| 497 } else { |
| 498 return FullCodeGenerator::NewCompilationJob(info); |
471 } | 499 } |
472 return info->code()->SizeIncludingMetadata(); | |
473 } | 500 } |
474 | 501 |
475 bool GenerateUnoptimizedCode(CompilationInfo* info) { | 502 bool GenerateUnoptimizedCode(CompilationInfo* info) { |
476 bool success; | |
477 EnsureFeedbackMetadata(info); | |
478 if (FLAG_validate_asm && info->scope()->asm_module() && | 503 if (FLAG_validate_asm && info->scope()->asm_module() && |
479 !info->shared_info()->is_asm_wasm_broken()) { | 504 !info->shared_info()->is_asm_wasm_broken()) { |
480 MaybeHandle<FixedArray> wasm_data; | 505 MaybeHandle<FixedArray> wasm_data; |
481 wasm_data = AsmJs::ConvertAsmToWasm(info->parse_info()); | 506 wasm_data = AsmJs::ConvertAsmToWasm(info->parse_info()); |
482 if (!wasm_data.is_null()) { | 507 if (!wasm_data.is_null()) { |
483 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); | 508 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); |
484 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); | 509 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); |
485 return true; | 510 return true; |
486 } | 511 } |
487 } | 512 } |
488 if (ShouldUseIgnition(info)) { | 513 |
489 success = interpreter::Interpreter::MakeBytecode(info); | 514 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); |
490 } else { | 515 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; |
491 success = FullCodeGenerator::MakeCode(info); | 516 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; |
492 } | 517 if (job->FinalizeJob() != CompilationJob::SUCCEEDED) return false; |
493 if (success) { | 518 return true; |
494 Isolate* isolate = info->isolate(); | |
495 Counters* counters = isolate->counters(); | |
496 // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually. | |
497 counters->total_baseline_code_size()->Increment(CodeAndMetadataSize(info)); | |
498 counters->total_baseline_compile_count()->Increment(1); | |
499 } | |
500 return success; | |
501 } | 519 } |
502 | 520 |
503 bool CompileUnoptimizedCode(CompilationInfo* info) { | 521 bool CompileUnoptimizedCode(CompilationInfo* info) { |
504 DCHECK(AllowCompilation::IsAllowed(info->isolate())); | 522 DCHECK(AllowCompilation::IsAllowed(info->isolate())); |
505 if (!Compiler::Analyze(info->parse_info()) || | 523 if (!Compiler::Analyze(info->parse_info()) || |
506 !GenerateUnoptimizedCode(info)) { | 524 !GenerateUnoptimizedCode(info)) { |
507 Isolate* isolate = info->isolate(); | 525 Isolate* isolate = info->isolate(); |
508 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 526 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
509 return false; | 527 return false; |
510 } | 528 } |
(...skipping 16 matching lines...) Expand all Loading... |
527 shared->ClearBytecodeArray(); | 545 shared->ClearBytecodeArray(); |
528 } | 546 } |
529 DCHECK(!info->code().is_null()); | 547 DCHECK(!info->code().is_null()); |
530 shared->ReplaceCode(*info->code()); | 548 shared->ReplaceCode(*info->code()); |
531 if (info->has_bytecode_array()) { | 549 if (info->has_bytecode_array()) { |
532 DCHECK(!shared->HasBytecodeArray()); // Only compiled once. | 550 DCHECK(!shared->HasBytecodeArray()); // Only compiled once. |
533 shared->set_bytecode_array(*info->bytecode_array()); | 551 shared->set_bytecode_array(*info->bytecode_array()); |
534 } | 552 } |
535 } | 553 } |
536 | 554 |
| 555 void InstallUnoptimizedCode(CompilationInfo* info) { |
| 556 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 557 |
| 558 // Update the shared function info with the scope info. |
| 559 InstallSharedScopeInfo(info, shared); |
| 560 |
| 561 // Install compilation result on the shared function info |
| 562 InstallSharedCompilationResult(info, shared); |
| 563 |
| 564 // Record the function compilation event. |
| 565 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
| 566 } |
| 567 |
537 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { | 568 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { |
538 VMState<COMPILER> state(info->isolate()); | 569 VMState<COMPILER> state(info->isolate()); |
539 PostponeInterruptsScope postpone(info->isolate()); | 570 PostponeInterruptsScope postpone(info->isolate()); |
540 | 571 |
541 // Create a canonical handle scope before internalizing parsed values if | 572 // Create a canonical handle scope before internalizing parsed values if |
542 // compiling bytecode. This is required for off-thread bytecode generation. | 573 // compiling bytecode. This is required for off-thread bytecode generation. |
543 std::unique_ptr<CanonicalHandleScope> canonical; | 574 std::unique_ptr<CanonicalHandleScope> canonical; |
544 if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(info->isolate())); | 575 if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(info->isolate())); |
545 | 576 |
546 // Parse and update CompilationInfo with the results. | 577 // Parse and update CompilationInfo with the results. |
547 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); | 578 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); |
548 Handle<SharedFunctionInfo> shared = info->shared_info(); | 579 DCHECK_EQ(info->shared_info()->language_mode(), |
549 DCHECK_EQ(shared->language_mode(), info->literal()->language_mode()); | 580 info->literal()->language_mode()); |
550 | 581 |
551 // Compile either unoptimized code or bytecode for the interpreter. | 582 // Compile either unoptimized code or bytecode for the interpreter. |
552 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); | 583 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
553 | 584 |
554 // Update the shared function info with the scope info. | 585 InstallUnoptimizedCode(info); |
555 InstallSharedScopeInfo(info, shared); | |
556 | |
557 // Install compilation result on the shared function info | |
558 InstallSharedCompilationResult(info, shared); | |
559 | |
560 // Record the function compilation event. | |
561 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); | |
562 | 586 |
563 return info->code(); | 587 return info->code(); |
564 } | 588 } |
565 | 589 |
| 590 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { |
| 591 CompilationJob::Status status = job->FinalizeJob(); |
| 592 if (status == CompilationJob::SUCCEEDED) { |
| 593 InstallUnoptimizedCode(job->info()); |
| 594 } |
| 595 return status; |
| 596 } |
| 597 |
566 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( | 598 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( |
567 Handle<JSFunction> function, BailoutId osr_ast_id) { | 599 Handle<JSFunction> function, BailoutId osr_ast_id) { |
568 Handle<SharedFunctionInfo> shared(function->shared()); | 600 Handle<SharedFunctionInfo> shared(function->shared()); |
569 DisallowHeapAllocation no_gc; | 601 DisallowHeapAllocation no_gc; |
570 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( | 602 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( |
571 function->context()->native_context(), osr_ast_id); | 603 function->context()->native_context(), osr_ast_id); |
572 if (cached.code != nullptr) { | 604 if (cached.code != nullptr) { |
573 // Caching of optimized code enabled and optimized code found. | 605 // Caching of optimized code enabled and optimized code found. |
574 if (cached.literals != nullptr) function->set_literals(cached.literals); | 606 if (cached.literals != nullptr) function->set_literals(cached.literals); |
575 DCHECK(!cached.code->marked_for_deoptimization()); | 607 DCHECK(!cached.code->marked_for_deoptimization()); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 job->FinalizeJob() != CompilationJob::SUCCEEDED) { | 709 job->FinalizeJob() != CompilationJob::SUCCEEDED) { |
678 if (FLAG_trace_opt) { | 710 if (FLAG_trace_opt) { |
679 PrintF("[aborted optimizing "); | 711 PrintF("[aborted optimizing "); |
680 info->closure()->ShortPrint(); | 712 info->closure()->ShortPrint(); |
681 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); | 713 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
682 } | 714 } |
683 return false; | 715 return false; |
684 } | 716 } |
685 | 717 |
686 // Success! | 718 // Success! |
687 job->RecordOptimizationStats(); | |
688 DCHECK(!isolate->has_pending_exception()); | 719 DCHECK(!isolate->has_pending_exception()); |
689 InsertCodeIntoOptimizedCodeMap(info); | 720 InsertCodeIntoOptimizedCodeMap(info); |
690 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); | 721 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
691 return true; | 722 return true; |
692 } | 723 } |
693 | 724 |
694 bool GetOptimizedCodeLater(CompilationJob* job) { | 725 bool GetOptimizedCodeLater(CompilationJob* job) { |
695 CompilationInfo* info = job->info(); | 726 CompilationInfo* info = job->info(); |
696 Isolate* isolate = info->isolate(); | 727 Isolate* isolate = info->isolate(); |
697 | 728 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 return isolate->builtins()->InOptimizationQueue(); | 868 return isolate->builtins()->InOptimizationQueue(); |
838 } | 869 } |
839 } else { | 870 } else { |
840 if (GetOptimizedCodeNow(job.get())) return info->code(); | 871 if (GetOptimizedCodeNow(job.get())) return info->code(); |
841 } | 872 } |
842 | 873 |
843 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); | 874 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); |
844 return MaybeHandle<Code>(); | 875 return MaybeHandle<Code>(); |
845 } | 876 } |
846 | 877 |
| 878 CompilationJob::Status FinalizeOptimizedCompilationJob(CompilationJob* job) { |
| 879 CompilationInfo* info = job->info(); |
| 880 Isolate* isolate = info->isolate(); |
| 881 |
| 882 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
| 883 RuntimeCallTimerScope runtimeTimer(isolate, |
| 884 &RuntimeCallStats::RecompileSynchronous); |
| 885 TRACE_EVENT_RUNTIME_CALL_STATS_TRACING_SCOPED( |
| 886 isolate, &tracing::TraceEventStatsTable::RecompileSynchronous); |
| 887 |
| 888 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 889 shared->code()->set_profiler_ticks(0); |
| 890 |
| 891 DCHECK(!shared->HasDebugInfo()); |
| 892 |
| 893 // 1) Optimization on the concurrent thread may have failed. |
| 894 // 2) The function may have already been optimized by OSR. Simply continue. |
| 895 // Except when OSR already disabled optimization for some reason. |
| 896 // 3) The code may have already been invalidated due to dependency change. |
| 897 // 4) Code generation may have failed. |
| 898 if (job->state() == CompilationJob::State::kReadyToFinalize) { |
| 899 if (shared->optimization_disabled()) { |
| 900 job->RetryOptimization(kOptimizationDisabled); |
| 901 } else if (info->dependencies()->HasAborted()) { |
| 902 job->RetryOptimization(kBailedOutDueToDependencyChange); |
| 903 } else if (job->FinalizeJob() == CompilationJob::SUCCEEDED) { |
| 904 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
| 905 if (shared |
| 906 ->SearchOptimizedCodeMap(info->context()->native_context(), |
| 907 info->osr_ast_id()) |
| 908 .code == nullptr) { |
| 909 InsertCodeIntoOptimizedCodeMap(info); |
| 910 } |
| 911 if (FLAG_trace_opt) { |
| 912 PrintF("[completed optimizing "); |
| 913 info->closure()->ShortPrint(); |
| 914 PrintF("]\n"); |
| 915 } |
| 916 info->closure()->ReplaceCode(*info->code()); |
| 917 return CompilationJob::SUCCEEDED; |
| 918 } |
| 919 } |
| 920 |
| 921 DCHECK(job->state() == CompilationJob::State::kFailed); |
| 922 if (FLAG_trace_opt) { |
| 923 PrintF("[aborted optimizing "); |
| 924 info->closure()->ShortPrint(); |
| 925 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
| 926 } |
| 927 info->closure()->ReplaceCode(shared->code()); |
| 928 return CompilationJob::FAILED; |
| 929 } |
| 930 |
847 class InterpreterActivationsFinder : public ThreadVisitor, | 931 class InterpreterActivationsFinder : public ThreadVisitor, |
848 public OptimizedFunctionVisitor { | 932 public OptimizedFunctionVisitor { |
849 public: | 933 public: |
850 explicit InterpreterActivationsFinder(SharedFunctionInfo* shared) | 934 explicit InterpreterActivationsFinder(SharedFunctionInfo* shared) |
851 : shared_(shared), has_activations_(false) {} | 935 : shared_(shared), has_activations_(false) {} |
852 | 936 |
853 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { | 937 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { |
854 Address* activation_pc_address = nullptr; | 938 Address* activation_pc_address = nullptr; |
855 JavaScriptFrameIterator it(isolate, top); | 939 JavaScriptFrameIterator it(isolate, top); |
856 for (; !it.done(); it.Advance()) { | 940 for (; !it.done(); it.Advance()) { |
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1881 } | 1965 } |
1882 | 1966 |
1883 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, | 1967 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, |
1884 BailoutId osr_ast_id, | 1968 BailoutId osr_ast_id, |
1885 JavaScriptFrame* osr_frame) { | 1969 JavaScriptFrame* osr_frame) { |
1886 DCHECK(!osr_ast_id.IsNone()); | 1970 DCHECK(!osr_ast_id.IsNone()); |
1887 DCHECK_NOT_NULL(osr_frame); | 1971 DCHECK_NOT_NULL(osr_frame); |
1888 return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame); | 1972 return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame); |
1889 } | 1973 } |
1890 | 1974 |
1891 void Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { | 1975 CompilationJob* Compiler::PrepareUnoptimizedCompilationJob( |
| 1976 CompilationInfo* info) { |
| 1977 VMState<COMPILER> state(info->isolate()); |
| 1978 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); |
| 1979 if (job->PrepareJob() != CompilationJob::SUCCEEDED) { |
| 1980 return nullptr; |
| 1981 } |
| 1982 return job.release(); |
| 1983 } |
| 1984 |
| 1985 bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { |
1892 // Take ownership of compilation job. Deleting job also tears down the zone. | 1986 // Take ownership of compilation job. Deleting job also tears down the zone. |
1893 std::unique_ptr<CompilationJob> job(raw_job); | 1987 std::unique_ptr<CompilationJob> job(raw_job); |
1894 CompilationInfo* info = job->info(); | |
1895 Isolate* isolate = info->isolate(); | |
1896 | 1988 |
1897 VMState<COMPILER> state(isolate); | 1989 VMState<COMPILER> state(job->info()->isolate()); |
1898 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); | 1990 CompilationJob::Status status; |
1899 RuntimeCallTimerScope runtimeTimer(isolate, | 1991 if (job->info()->IsOptimizing()) { |
1900 &RuntimeCallStats::RecompileSynchronous); | 1992 status = FinalizeOptimizedCompilationJob(job.get()); |
1901 TRACE_EVENT_RUNTIME_CALL_STATS_TRACING_SCOPED( | 1993 } else { |
1902 isolate, &tracing::TraceEventStatsTable::RecompileSynchronous); | 1994 status = FinalizeUnoptimizedCompilationJob(job.get()); |
1903 | |
1904 Handle<SharedFunctionInfo> shared = info->shared_info(); | |
1905 shared->code()->set_profiler_ticks(0); | |
1906 | |
1907 DCHECK(!shared->HasDebugInfo()); | |
1908 | |
1909 // 1) Optimization on the concurrent thread may have failed. | |
1910 // 2) The function may have already been optimized by OSR. Simply continue. | |
1911 // Except when OSR already disabled optimization for some reason. | |
1912 // 3) The code may have already been invalidated due to dependency change. | |
1913 // 4) Code generation may have failed. | |
1914 if (job->state() == CompilationJob::State::kReadyToFinalize) { | |
1915 if (shared->optimization_disabled()) { | |
1916 job->RetryOptimization(kOptimizationDisabled); | |
1917 } else if (info->dependencies()->HasAborted()) { | |
1918 job->RetryOptimization(kBailedOutDueToDependencyChange); | |
1919 } else if (job->FinalizeJob() == CompilationJob::SUCCEEDED) { | |
1920 job->RecordOptimizationStats(); | |
1921 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); | |
1922 if (shared->SearchOptimizedCodeMap(info->context()->native_context(), | |
1923 info->osr_ast_id()).code == nullptr) { | |
1924 InsertCodeIntoOptimizedCodeMap(info); | |
1925 } | |
1926 if (FLAG_trace_opt) { | |
1927 PrintF("[completed optimizing "); | |
1928 info->closure()->ShortPrint(); | |
1929 PrintF("]\n"); | |
1930 } | |
1931 info->closure()->ReplaceCode(*info->code()); | |
1932 return; | |
1933 } | |
1934 } | 1995 } |
1935 | 1996 if (status == CompilationJob::SUCCEEDED) { |
1936 DCHECK(job->state() == CompilationJob::State::kFailed); | 1997 job->RecordCompilationStats(); |
1937 if (FLAG_trace_opt) { | |
1938 PrintF("[aborted optimizing "); | |
1939 info->closure()->ShortPrint(); | |
1940 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); | |
1941 } | 1998 } |
1942 info->closure()->ReplaceCode(shared->code()); | 1999 return status == CompilationJob::SUCCEEDED; |
1943 } | 2000 } |
1944 | 2001 |
1945 void Compiler::PostInstantiation(Handle<JSFunction> function, | 2002 void Compiler::PostInstantiation(Handle<JSFunction> function, |
1946 PretenureFlag pretenure) { | 2003 PretenureFlag pretenure) { |
1947 Handle<SharedFunctionInfo> shared(function->shared()); | 2004 Handle<SharedFunctionInfo> shared(function->shared()); |
1948 | 2005 |
1949 if (FLAG_always_opt && shared->allows_lazy_compilation()) { | 2006 if (FLAG_always_opt && shared->allows_lazy_compilation()) { |
1950 function->MarkForOptimization(); | 2007 function->MarkForOptimization(); |
1951 } | 2008 } |
1952 | 2009 |
(...skipping 10 matching lines...) Expand all Loading... |
1963 DCHECK(shared->is_compiled()); | 2020 DCHECK(shared->is_compiled()); |
1964 function->set_literals(cached.literals); | 2021 function->set_literals(cached.literals); |
1965 } else if (shared->is_compiled()) { | 2022 } else if (shared->is_compiled()) { |
1966 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 2023 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
1967 JSFunction::EnsureLiterals(function); | 2024 JSFunction::EnsureLiterals(function); |
1968 } | 2025 } |
1969 } | 2026 } |
1970 | 2027 |
1971 } // namespace internal | 2028 } // namespace internal |
1972 } // namespace v8 | 2029 } // namespace v8 |
OLD | NEW |