Chromium Code Reviews

Side by Side Diff: src/compiler.cc

Issue 1906823002: Move of the type feedback vector to the closure. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « src/code-stubs-hydrogen.cc ('k') | src/compiler/access-builder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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...)
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...)
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...)
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...)
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...)
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...)
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...)
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...)
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...)
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
OLDNEW
« no previous file with comments | « src/code-stubs-hydrogen.cc ('k') | src/compiler/access-builder.h » ('j') | no next file with comments »

Powered by Google App Engine