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" |
(...skipping 388 matching lines...) Loading... | |
399 String* script_name = script->name()->IsString() | 399 String* script_name = script->name()->IsString() |
400 ? String::cast(script->name()) | 400 ? String::cast(script->name()) |
401 : info->isolate()->heap()->empty_string(); | 401 : info->isolate()->heap()->empty_string(); |
402 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script); | 402 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script); |
403 PROFILE(info->isolate(), | 403 PROFILE(info->isolate(), |
404 CodeCreateEvent(log_tag, *abstract_code, *shared, script_name, | 404 CodeCreateEvent(log_tag, *abstract_code, *shared, script_name, |
405 line_num, column_num)); | 405 line_num, column_num)); |
406 } | 406 } |
407 } | 407 } |
408 | 408 |
409 void EnsureFeedbackVector(CompilationInfo* info) { | 409 void EnsureFeedbackMetadata(CompilationInfo* info) { |
410 DCHECK(info->has_shared_info()); | 410 DCHECK(info->has_shared_info()); |
411 | 411 |
412 // If no type feedback vector exists, we create one now. At this point the | 412 // If no type feedback metadata exists, we create it now. At this point the |
413 // AstNumbering pass has already run. Note the snapshot can contain outdated | 413 // AstNumbering pass has already run. Note the snapshot can contain outdated |
414 // vectors for a different configuration, hence we also recreate a new vector | 414 // vectors for a different configuration, hence we also recreate a new vector |
415 // when the function is not compiled (i.e. no code was serialized). | 415 // when the function is not compiled (i.e. no code was serialized). |
416 if (info->shared_info()->feedback_vector()->is_empty() || | 416 |
417 // TODO(mvstanton): reintroduce is_empty() predicate to feedback_metadata(). | |
418 if (info->shared_info()->feedback_metadata()->length() == 0 || | |
417 !info->shared_info()->is_compiled()) { | 419 !info->shared_info()->is_compiled()) { |
418 Handle<TypeFeedbackMetadata> feedback_metadata = TypeFeedbackMetadata::New( | 420 Handle<TypeFeedbackMetadata> feedback_metadata = TypeFeedbackMetadata::New( |
419 info->isolate(), info->literal()->feedback_vector_spec()); | 421 info->isolate(), info->literal()->feedback_vector_spec()); |
420 Handle<TypeFeedbackVector> feedback_vector = | 422 info->shared_info()->set_feedback_metadata(*feedback_metadata); |
421 TypeFeedbackVector::New(info->isolate(), feedback_metadata); | |
422 info->shared_info()->set_feedback_vector(*feedback_vector); | |
423 } | 423 } |
424 | 424 |
425 // It's very important that recompiles do not alter the structure of the type | 425 // It's very important that recompiles do not alter the structure of the type |
426 // feedback vector. Verify that the structure fits the function literal. | 426 // feedback vector. Verify that the structure fits the function literal. |
427 CHECK(!info->shared_info()->feedback_vector()->metadata()->SpecDiffersFrom( | 427 CHECK(!info->shared_info()->feedback_metadata()->SpecDiffersFrom( |
428 info->literal()->feedback_vector_spec())); | 428 info->literal()->feedback_vector_spec())); |
429 } | 429 } |
430 | 430 |
431 bool UseIgnition(CompilationInfo* info) { | 431 bool UseIgnition(CompilationInfo* info) { |
432 if (info->is_debug()) return false; | 432 if (info->is_debug()) return false; |
433 if (info->shared_info()->is_resumable() && !FLAG_ignition_generators) { | 433 if (info->shared_info()->is_resumable() && !FLAG_ignition_generators) { |
434 return false; | 434 return false; |
435 } | 435 } |
436 | 436 |
437 // Checks whether top level functions should be passed by the filter. | 437 // Checks whether top level functions should be passed by the filter. |
(...skipping 19 matching lines...) Loading... | |
457 size += code->CodeSize(); | 457 size += code->CodeSize(); |
458 size += code->relocation_info()->Size(); | 458 size += code->relocation_info()->Size(); |
459 size += code->deoptimization_data()->Size(); | 459 size += code->deoptimization_data()->Size(); |
460 size += code->handler_table()->Size(); | 460 size += code->handler_table()->Size(); |
461 } | 461 } |
462 return size; | 462 return size; |
463 } | 463 } |
464 | 464 |
465 bool GenerateUnoptimizedCode(CompilationInfo* info) { | 465 bool GenerateUnoptimizedCode(CompilationInfo* info) { |
466 bool success; | 466 bool success; |
467 EnsureFeedbackVector(info); | 467 EnsureFeedbackMetadata(info); |
468 if (FLAG_validate_asm && info->scope()->asm_module()) { | 468 if (FLAG_validate_asm && info->scope()->asm_module()) { |
469 AsmTyper typer(info->isolate(), info->zone(), *(info->script()), | 469 AsmTyper typer(info->isolate(), info->zone(), *(info->script()), |
470 info->literal()); | 470 info->literal()); |
471 if (FLAG_enable_simd_asmjs) { | 471 if (FLAG_enable_simd_asmjs) { |
472 typer.set_allow_simd(true); | 472 typer.set_allow_simd(true); |
473 } | 473 } |
474 if (!typer.Validate()) { | 474 if (!typer.Validate()) { |
475 DCHECK(!info->isolate()->has_pending_exception()); | 475 DCHECK(!info->isolate()->has_pending_exception()); |
476 PrintF("Validation of asm.js module failed: %s", typer.error_message()); | 476 PrintF("Validation of asm.js module failed: %s", typer.error_message()); |
477 } | 477 } |
(...skipping 154 matching lines...) Loading... | |
632 passes_turbo_filter; | 632 passes_turbo_filter; |
633 } | 633 } |
634 | 634 |
635 bool GetOptimizedCodeNow(CompilationJob* job) { | 635 bool GetOptimizedCodeNow(CompilationJob* job) { |
636 CompilationInfo* info = job->info(); | 636 CompilationInfo* info = job->info(); |
637 Isolate* isolate = info->isolate(); | 637 Isolate* isolate = info->isolate(); |
638 | 638 |
639 // Parsing is not required when optimizing from existing bytecode. | 639 // Parsing is not required when optimizing from existing bytecode. |
640 if (!info->is_optimizing_from_bytecode()) { | 640 if (!info->is_optimizing_from_bytecode()) { |
641 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; | 641 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
642 EnsureFeedbackMetadata(info); | |
642 } | 643 } |
643 | 644 |
645 JSFunction::EnsureLiterals(info->closure()); | |
646 | |
644 TimerEventScope<TimerEventRecompileSynchronous> timer(isolate); | 647 TimerEventScope<TimerEventRecompileSynchronous> timer(isolate); |
645 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); | 648 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); |
646 | 649 |
647 if (job->CreateGraph() != CompilationJob::SUCCEEDED || | 650 if (job->CreateGraph() != CompilationJob::SUCCEEDED || |
648 job->OptimizeGraph() != CompilationJob::SUCCEEDED || | 651 job->OptimizeGraph() != CompilationJob::SUCCEEDED || |
649 job->GenerateCode() != CompilationJob::SUCCEEDED) { | 652 job->GenerateCode() != CompilationJob::SUCCEEDED) { |
650 if (FLAG_trace_opt) { | 653 if (FLAG_trace_opt) { |
651 PrintF("[aborted optimizing "); | 654 PrintF("[aborted optimizing "); |
652 info->closure()->ShortPrint(); | 655 info->closure()->ShortPrint(); |
653 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); | 656 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
(...skipping 21 matching lines...) Loading... | |
675 } | 678 } |
676 return false; | 679 return false; |
677 } | 680 } |
678 | 681 |
679 // All handles below this point will be allocated in a deferred handle scope | 682 // All handles below this point will be allocated in a deferred handle scope |
680 // that is detached and handed off to the background thread when we return. | 683 // that is detached and handed off to the background thread when we return. |
681 CompilationHandleScope handle_scope(info); | 684 CompilationHandleScope handle_scope(info); |
682 | 685 |
683 // Parsing is not required when optimizing from existing bytecode. | 686 // Parsing is not required when optimizing from existing bytecode. |
684 if (!info->is_optimizing_from_bytecode()) { | 687 if (!info->is_optimizing_from_bytecode()) { |
685 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; | 688 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
Michael Starzinger
2016/05/25 11:20:18
If the call to EnsureFeedbackMetadata is needed fo
mvstanton
2016/05/25 12:57:07
Done.
| |
686 } | 689 } |
687 | 690 |
691 JSFunction::EnsureLiterals(info->closure()); | |
692 | |
688 // Reopen handles in the new CompilationHandleScope. | 693 // Reopen handles in the new CompilationHandleScope. |
689 info->ReopenHandlesInNewHandleScope(); | 694 info->ReopenHandlesInNewHandleScope(); |
690 info->parse_info()->ReopenHandlesInNewHandleScope(); | 695 info->parse_info()->ReopenHandlesInNewHandleScope(); |
691 | 696 |
692 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); | 697 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
693 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); | 698 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); |
694 | 699 |
695 if (job->CreateGraph() != CompilationJob::SUCCEEDED) return false; | 700 if (job->CreateGraph() != CompilationJob::SUCCEEDED) return false; |
696 isolate->optimizing_compile_dispatcher()->QueueForOptimization(job); | 701 isolate->optimizing_compile_dispatcher()->QueueForOptimization(job); |
697 | 702 |
(...skipping 440 matching lines...) Loading... | |
1138 Handle<Code> code; | 1143 Handle<Code> code; |
1139 if (!GetLazyCode(function).ToHandle(&code)) { | 1144 if (!GetLazyCode(function).ToHandle(&code)) { |
1140 if (flag == CLEAR_EXCEPTION) { | 1145 if (flag == CLEAR_EXCEPTION) { |
1141 isolate->clear_pending_exception(); | 1146 isolate->clear_pending_exception(); |
1142 } | 1147 } |
1143 return false; | 1148 return false; |
1144 } | 1149 } |
1145 | 1150 |
1146 // Install code on closure. | 1151 // Install code on closure. |
1147 function->ReplaceCode(*code); | 1152 function->ReplaceCode(*code); |
1153 JSFunction::EnsureLiterals(function); | |
1148 | 1154 |
1149 // Check postconditions on success. | 1155 // Check postconditions on success. |
1150 DCHECK(!isolate->has_pending_exception()); | 1156 DCHECK(!isolate->has_pending_exception()); |
1151 DCHECK(function->shared()->is_compiled()); | 1157 DCHECK(function->shared()->is_compiled()); |
1152 DCHECK(function->is_compiled()); | 1158 DCHECK(function->is_compiled()); |
1153 return true; | 1159 return true; |
1154 } | 1160 } |
1155 | 1161 |
1156 bool Compiler::CompileBaseline(Handle<JSFunction> function) { | 1162 bool Compiler::CompileBaseline(Handle<JSFunction> function) { |
1157 Isolate* isolate = function->GetIsolate(); | 1163 Isolate* isolate = function->GetIsolate(); |
(...skipping 36 matching lines...) Loading... | |
1194 ParseInfo parse_info(&zone, function); | 1200 ParseInfo parse_info(&zone, function); |
1195 CompilationInfo info(&parse_info, function); | 1201 CompilationInfo info(&parse_info, function); |
1196 if (!GetUnoptimizedCode(&info).ToHandle(&code)) { | 1202 if (!GetUnoptimizedCode(&info).ToHandle(&code)) { |
1197 return false; | 1203 return false; |
1198 } | 1204 } |
1199 } | 1205 } |
1200 } | 1206 } |
1201 | 1207 |
1202 // Install code on closure. | 1208 // Install code on closure. |
1203 function->ReplaceCode(*code); | 1209 function->ReplaceCode(*code); |
1210 JSFunction::EnsureLiterals(function); | |
1204 | 1211 |
1205 // Check postconditions on success. | 1212 // Check postconditions on success. |
1206 DCHECK(!isolate->has_pending_exception()); | 1213 DCHECK(!isolate->has_pending_exception()); |
1207 DCHECK(function->shared()->is_compiled()); | 1214 DCHECK(function->shared()->is_compiled()); |
1208 DCHECK(function->is_compiled()); | 1215 DCHECK(function->is_compiled()); |
1209 return true; | 1216 return true; |
1210 } | 1217 } |
1211 | 1218 |
1212 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { | 1219 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { |
1213 Isolate* isolate = function->GetIsolate(); | 1220 Isolate* isolate = function->GetIsolate(); |
(...skipping 110 matching lines...) Loading... | |
1324 } | 1331 } |
1325 } | 1332 } |
1326 | 1333 |
1327 // If the current code has reloc info for serialization, also include | 1334 // If the current code has reloc info for serialization, also include |
1328 // reloc info for serialization for the new code, so that deopt support | 1335 // reloc info for serialization for the new code, so that deopt support |
1329 // can be added without losing IC state. | 1336 // can be added without losing IC state. |
1330 if (shared->code()->kind() == Code::FUNCTION && | 1337 if (shared->code()->kind() == Code::FUNCTION && |
1331 shared->code()->has_reloc_info_for_serialization()) { | 1338 shared->code()->has_reloc_info_for_serialization()) { |
1332 unoptimized.PrepareForSerializing(); | 1339 unoptimized.PrepareForSerializing(); |
1333 } | 1340 } |
1334 EnsureFeedbackVector(&unoptimized); | 1341 EnsureFeedbackMetadata(&unoptimized); |
1335 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; | 1342 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; |
1336 | 1343 |
1337 // TODO(4280): For now we play it safe and remove the bytecode array when we | 1344 // TODO(4280): For now we play it safe and remove the bytecode array when we |
1338 // switch to baseline code. We might consider keeping around the bytecode so | 1345 // switch to baseline code. We might consider keeping around the bytecode so |
1339 // that it can be used as the "source of truth" eventually. | 1346 // that it can be used as the "source of truth" eventually. |
1340 shared->ClearBytecodeArray(); | 1347 shared->ClearBytecodeArray(); |
1341 | 1348 |
1342 // The scope info might not have been set if a lazily compiled | 1349 // The scope info might not have been set if a lazily compiled |
1343 // function is inlined before being called for the first time. | 1350 // function is inlined before being called for the first time. |
1344 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { | 1351 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { |
(...skipping 340 matching lines...) Loading... | |
1685 // Instantiate the function and create a shared function info from it. | 1692 // Instantiate the function and create a shared function info from it. |
1686 Handle<JSFunction> fun = Handle<JSFunction>::cast(Utils::OpenHandle( | 1693 Handle<JSFunction> fun = Handle<JSFunction>::cast(Utils::OpenHandle( |
1687 *fun_template->GetFunction(v8_isolate->GetCurrentContext()) | 1694 *fun_template->GetFunction(v8_isolate->GetCurrentContext()) |
1688 .ToLocalChecked())); | 1695 .ToLocalChecked())); |
1689 Handle<Code> code = Handle<Code>(fun->shared()->code()); | 1696 Handle<Code> code = Handle<Code>(fun->shared()->code()); |
1690 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); | 1697 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); |
1691 Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( | 1698 Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( |
1692 name, fun->shared()->num_literals(), FunctionKind::kNormalFunction, code, | 1699 name, fun->shared()->num_literals(), FunctionKind::kNormalFunction, code, |
1693 Handle<ScopeInfo>(fun->shared()->scope_info())); | 1700 Handle<ScopeInfo>(fun->shared()->scope_info())); |
1694 shared->set_construct_stub(*construct_stub); | 1701 shared->set_construct_stub(*construct_stub); |
1695 shared->set_feedback_vector(fun->shared()->feedback_vector()); | 1702 shared->set_feedback_metadata(fun->shared()->feedback_metadata()); |
1696 | 1703 |
1697 // Copy the function data to the shared function info. | 1704 // Copy the function data to the shared function info. |
1698 shared->set_function_data(fun->shared()->function_data()); | 1705 shared->set_function_data(fun->shared()->function_data()); |
1699 int parameters = fun->shared()->internal_formal_parameter_count(); | 1706 int parameters = fun->shared()->internal_formal_parameter_count(); |
1700 shared->set_internal_formal_parameter_count(parameters); | 1707 shared->set_internal_formal_parameter_count(parameters); |
1701 | 1708 |
1702 return shared; | 1709 return shared; |
1703 } | 1710 } |
1704 | 1711 |
1705 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, | 1712 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, |
(...skipping 66 matching lines...) Loading... | |
1772 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( | 1779 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( |
1773 function->context()->native_context(), BailoutId::None()); | 1780 function->context()->native_context(), BailoutId::None()); |
1774 if (cached.code != nullptr) { | 1781 if (cached.code != nullptr) { |
1775 // Caching of optimized code enabled and optimized code found. | 1782 // Caching of optimized code enabled and optimized code found. |
1776 DCHECK(!cached.code->marked_for_deoptimization()); | 1783 DCHECK(!cached.code->marked_for_deoptimization()); |
1777 DCHECK(function->shared()->is_compiled()); | 1784 DCHECK(function->shared()->is_compiled()); |
1778 function->ReplaceCode(cached.code); | 1785 function->ReplaceCode(cached.code); |
1779 } | 1786 } |
1780 | 1787 |
1781 if (cached.literals != nullptr) { | 1788 if (cached.literals != nullptr) { |
1789 DCHECK(shared->is_compiled()); | |
1782 function->set_literals(cached.literals); | 1790 function->set_literals(cached.literals); |
1783 } else { | 1791 } else if (shared->is_compiled()) { |
1784 Isolate* isolate = function->GetIsolate(); | 1792 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
1785 int number_of_literals = shared->num_literals(); | 1793 JSFunction::EnsureLiterals(function); |
1786 Handle<LiteralsArray> literals = | |
1787 LiteralsArray::New(isolate, handle(shared->feedback_vector()), | |
1788 number_of_literals, pretenure); | |
1789 function->set_literals(*literals); | |
1790 | |
1791 // Cache context-specific literals. | |
1792 MaybeHandle<Code> code; | |
1793 if (cached.code != nullptr) code = handle(cached.code); | |
1794 Handle<Context> native_context(function->context()->native_context()); | |
1795 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | |
1796 literals, BailoutId::None()); | |
1797 } | 1794 } |
1798 } | 1795 } |
1799 | 1796 |
1800 } // namespace internal | 1797 } // namespace internal |
1801 } // namespace v8 | 1798 } // namespace v8 |
OLD | NEW |