Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

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, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« 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...) Expand 10 before | Expand all | Expand 10 after
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 // Since we can't OSR from Ignition, skip Ignition for asm.js functions. 437 // Since we can't OSR from Ignition, skip Ignition for asm.js functions.
(...skipping 13 matching lines...) Expand all
451 451
452 int CodeAndMetadataSize(CompilationInfo* info) { 452 int CodeAndMetadataSize(CompilationInfo* info) {
453 if (info->has_bytecode_array()) { 453 if (info->has_bytecode_array()) {
454 return info->bytecode_array()->SizeIncludingMetadata(); 454 return info->bytecode_array()->SizeIncludingMetadata();
455 } 455 }
456 return info->code()->SizeIncludingMetadata(); 456 return info->code()->SizeIncludingMetadata();
457 } 457 }
458 458
459 bool GenerateUnoptimizedCode(CompilationInfo* info) { 459 bool GenerateUnoptimizedCode(CompilationInfo* info) {
460 bool success; 460 bool success;
461 EnsureFeedbackVector(info); 461 EnsureFeedbackMetadata(info);
462 if (FLAG_validate_asm && info->scope()->asm_module()) { 462 if (FLAG_validate_asm && info->scope()->asm_module()) {
463 AsmTyper typer(info->isolate(), info->zone(), *(info->script()), 463 AsmTyper typer(info->isolate(), info->zone(), *(info->script()),
464 info->literal()); 464 info->literal());
465 if (FLAG_enable_simd_asmjs) { 465 if (FLAG_enable_simd_asmjs) {
466 typer.set_allow_simd(true); 466 typer.set_allow_simd(true);
467 } 467 }
468 if (!typer.Validate()) { 468 if (!typer.Validate()) {
469 DCHECK(!info->isolate()->has_pending_exception()); 469 DCHECK(!info->isolate()->has_pending_exception());
470 PrintF("Validation of asm.js module failed: %s", typer.error_message()); 470 PrintF("Validation of asm.js module failed: %s", typer.error_message());
471 } 471 }
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 passes_turbo_filter; 626 passes_turbo_filter;
627 } 627 }
628 628
629 bool GetOptimizedCodeNow(CompilationJob* job) { 629 bool GetOptimizedCodeNow(CompilationJob* job) {
630 CompilationInfo* info = job->info(); 630 CompilationInfo* info = job->info();
631 Isolate* isolate = info->isolate(); 631 Isolate* isolate = info->isolate();
632 632
633 // Parsing is not required when optimizing from existing bytecode. 633 // Parsing is not required when optimizing from existing bytecode.
634 if (!info->is_optimizing_from_bytecode()) { 634 if (!info->is_optimizing_from_bytecode()) {
635 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; 635 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false;
636 EnsureFeedbackMetadata(info);
636 } 637 }
637 638
639 JSFunction::EnsureLiterals(info->closure());
640
638 TimerEventScope<TimerEventRecompileSynchronous> timer(isolate); 641 TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
639 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); 642 TRACE_EVENT0("v8", "V8.RecompileSynchronous");
640 643
641 if (job->CreateGraph() != CompilationJob::SUCCEEDED || 644 if (job->CreateGraph() != CompilationJob::SUCCEEDED ||
642 job->OptimizeGraph() != CompilationJob::SUCCEEDED || 645 job->OptimizeGraph() != CompilationJob::SUCCEEDED ||
643 job->GenerateCode() != CompilationJob::SUCCEEDED) { 646 job->GenerateCode() != CompilationJob::SUCCEEDED) {
644 if (FLAG_trace_opt) { 647 if (FLAG_trace_opt) {
645 PrintF("[aborted optimizing "); 648 PrintF("[aborted optimizing ");
646 info->closure()->ShortPrint(); 649 info->closure()->ShortPrint();
647 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); 650 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason()));
(...skipping 22 matching lines...) Expand all
670 return false; 673 return false;
671 } 674 }
672 675
673 // All handles below this point will be allocated in a deferred handle scope 676 // All handles below this point will be allocated in a deferred handle scope
674 // that is detached and handed off to the background thread when we return. 677 // that is detached and handed off to the background thread when we return.
675 CompilationHandleScope handle_scope(info); 678 CompilationHandleScope handle_scope(info);
676 679
677 // Parsing is not required when optimizing from existing bytecode. 680 // Parsing is not required when optimizing from existing bytecode.
678 if (!info->is_optimizing_from_bytecode()) { 681 if (!info->is_optimizing_from_bytecode()) {
679 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; 682 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false;
683 EnsureFeedbackMetadata(info);
680 } 684 }
681 685
686 JSFunction::EnsureLiterals(info->closure());
687
682 // Reopen handles in the new CompilationHandleScope. 688 // Reopen handles in the new CompilationHandleScope.
683 info->ReopenHandlesInNewHandleScope(); 689 info->ReopenHandlesInNewHandleScope();
684 info->parse_info()->ReopenHandlesInNewHandleScope(); 690 info->parse_info()->ReopenHandlesInNewHandleScope();
685 691
686 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); 692 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate());
687 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); 693 TRACE_EVENT0("v8", "V8.RecompileSynchronous");
688 694
689 if (job->CreateGraph() != CompilationJob::SUCCEEDED) return false; 695 if (job->CreateGraph() != CompilationJob::SUCCEEDED) return false;
690 isolate->optimizing_compile_dispatcher()->QueueForOptimization(job); 696 isolate->optimizing_compile_dispatcher()->QueueForOptimization(job);
691 697
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 Handle<Code> code; 1138 Handle<Code> code;
1133 if (!GetLazyCode(function).ToHandle(&code)) { 1139 if (!GetLazyCode(function).ToHandle(&code)) {
1134 if (flag == CLEAR_EXCEPTION) { 1140 if (flag == CLEAR_EXCEPTION) {
1135 isolate->clear_pending_exception(); 1141 isolate->clear_pending_exception();
1136 } 1142 }
1137 return false; 1143 return false;
1138 } 1144 }
1139 1145
1140 // Install code on closure. 1146 // Install code on closure.
1141 function->ReplaceCode(*code); 1147 function->ReplaceCode(*code);
1148 JSFunction::EnsureLiterals(function);
1142 1149
1143 // Check postconditions on success. 1150 // Check postconditions on success.
1144 DCHECK(!isolate->has_pending_exception()); 1151 DCHECK(!isolate->has_pending_exception());
1145 DCHECK(function->shared()->is_compiled()); 1152 DCHECK(function->shared()->is_compiled());
1146 DCHECK(function->is_compiled()); 1153 DCHECK(function->is_compiled());
1147 return true; 1154 return true;
1148 } 1155 }
1149 1156
1150 bool Compiler::CompileBaseline(Handle<JSFunction> function) { 1157 bool Compiler::CompileBaseline(Handle<JSFunction> function) {
1151 Isolate* isolate = function->GetIsolate(); 1158 Isolate* isolate = function->GetIsolate();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 ParseInfo parse_info(&zone, function); 1195 ParseInfo parse_info(&zone, function);
1189 CompilationInfo info(&parse_info, function); 1196 CompilationInfo info(&parse_info, function);
1190 if (!GetUnoptimizedCode(&info).ToHandle(&code)) { 1197 if (!GetUnoptimizedCode(&info).ToHandle(&code)) {
1191 return false; 1198 return false;
1192 } 1199 }
1193 } 1200 }
1194 } 1201 }
1195 1202
1196 // Install code on closure. 1203 // Install code on closure.
1197 function->ReplaceCode(*code); 1204 function->ReplaceCode(*code);
1205 JSFunction::EnsureLiterals(function);
1198 1206
1199 // Check postconditions on success. 1207 // Check postconditions on success.
1200 DCHECK(!isolate->has_pending_exception()); 1208 DCHECK(!isolate->has_pending_exception());
1201 DCHECK(function->shared()->is_compiled()); 1209 DCHECK(function->shared()->is_compiled());
1202 DCHECK(function->is_compiled()); 1210 DCHECK(function->is_compiled());
1203 return true; 1211 return true;
1204 } 1212 }
1205 1213
1206 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { 1214 bool Compiler::CompileDebugCode(Handle<JSFunction> function) {
1207 Isolate* isolate = function->GetIsolate(); 1215 Isolate* isolate = function->GetIsolate();
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 } 1326 }
1319 } 1327 }
1320 1328
1321 // If the current code has reloc info for serialization, also include 1329 // If the current code has reloc info for serialization, also include
1322 // reloc info for serialization for the new code, so that deopt support 1330 // reloc info for serialization for the new code, so that deopt support
1323 // can be added without losing IC state. 1331 // can be added without losing IC state.
1324 if (shared->code()->kind() == Code::FUNCTION && 1332 if (shared->code()->kind() == Code::FUNCTION &&
1325 shared->code()->has_reloc_info_for_serialization()) { 1333 shared->code()->has_reloc_info_for_serialization()) {
1326 unoptimized.PrepareForSerializing(); 1334 unoptimized.PrepareForSerializing();
1327 } 1335 }
1328 EnsureFeedbackVector(&unoptimized); 1336 EnsureFeedbackMetadata(&unoptimized);
1329 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; 1337 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false;
1330 1338
1331 // TODO(4280): For now we play it safe and remove the bytecode array when we 1339 // TODO(4280): For now we play it safe and remove the bytecode array when we
1332 // switch to baseline code. We might consider keeping around the bytecode so 1340 // switch to baseline code. We might consider keeping around the bytecode so
1333 // that it can be used as the "source of truth" eventually. 1341 // that it can be used as the "source of truth" eventually.
1334 shared->ClearBytecodeArray(); 1342 shared->ClearBytecodeArray();
1335 1343
1336 // The scope info might not have been set if a lazily compiled 1344 // The scope info might not have been set if a lazily compiled
1337 // function is inlined before being called for the first time. 1345 // function is inlined before being called for the first time.
1338 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { 1346 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 // Instantiate the function and create a shared function info from it. 1687 // Instantiate the function and create a shared function info from it.
1680 Handle<JSFunction> fun = Handle<JSFunction>::cast(Utils::OpenHandle( 1688 Handle<JSFunction> fun = Handle<JSFunction>::cast(Utils::OpenHandle(
1681 *fun_template->GetFunction(v8_isolate->GetCurrentContext()) 1689 *fun_template->GetFunction(v8_isolate->GetCurrentContext())
1682 .ToLocalChecked())); 1690 .ToLocalChecked()));
1683 Handle<Code> code = Handle<Code>(fun->shared()->code()); 1691 Handle<Code> code = Handle<Code>(fun->shared()->code());
1684 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); 1692 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
1685 Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( 1693 Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo(
1686 name, fun->shared()->num_literals(), FunctionKind::kNormalFunction, code, 1694 name, fun->shared()->num_literals(), FunctionKind::kNormalFunction, code,
1687 Handle<ScopeInfo>(fun->shared()->scope_info())); 1695 Handle<ScopeInfo>(fun->shared()->scope_info()));
1688 shared->set_construct_stub(*construct_stub); 1696 shared->set_construct_stub(*construct_stub);
1689 shared->set_feedback_vector(fun->shared()->feedback_vector()); 1697 shared->set_feedback_metadata(fun->shared()->feedback_metadata());
1690 1698
1691 // Copy the function data to the shared function info. 1699 // Copy the function data to the shared function info.
1692 shared->set_function_data(fun->shared()->function_data()); 1700 shared->set_function_data(fun->shared()->function_data());
1693 int parameters = fun->shared()->internal_formal_parameter_count(); 1701 int parameters = fun->shared()->internal_formal_parameter_count();
1694 shared->set_internal_formal_parameter_count(parameters); 1702 shared->set_internal_formal_parameter_count(parameters);
1695 1703
1696 return shared; 1704 return shared;
1697 } 1705 }
1698 1706
1699 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, 1707 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1766 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( 1774 CodeAndLiterals cached = shared->SearchOptimizedCodeMap(
1767 function->context()->native_context(), BailoutId::None()); 1775 function->context()->native_context(), BailoutId::None());
1768 if (cached.code != nullptr) { 1776 if (cached.code != nullptr) {
1769 // Caching of optimized code enabled and optimized code found. 1777 // Caching of optimized code enabled and optimized code found.
1770 DCHECK(!cached.code->marked_for_deoptimization()); 1778 DCHECK(!cached.code->marked_for_deoptimization());
1771 DCHECK(function->shared()->is_compiled()); 1779 DCHECK(function->shared()->is_compiled());
1772 function->ReplaceCode(cached.code); 1780 function->ReplaceCode(cached.code);
1773 } 1781 }
1774 1782
1775 if (cached.literals != nullptr) { 1783 if (cached.literals != nullptr) {
1784 DCHECK(shared->is_compiled());
1776 function->set_literals(cached.literals); 1785 function->set_literals(cached.literals);
1777 } else { 1786 } else if (shared->is_compiled()) {
1778 Isolate* isolate = function->GetIsolate(); 1787 // TODO(mvstanton): pass pretenure flag to EnsureLiterals.
1779 int number_of_literals = shared->num_literals(); 1788 JSFunction::EnsureLiterals(function);
1780 Handle<LiteralsArray> literals =
1781 LiteralsArray::New(isolate, handle(shared->feedback_vector()),
1782 number_of_literals, pretenure);
1783 function->set_literals(*literals);
1784
1785 // Cache context-specific literals.
1786 MaybeHandle<Code> code;
1787 if (cached.code != nullptr) code = handle(cached.code);
1788 Handle<Context> native_context(function->context()->native_context());
1789 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code,
1790 literals, BailoutId::None());
1791 } 1789 }
1792 } 1790 }
1793 1791
1794 } // namespace internal 1792 } // namespace internal
1795 } // namespace v8 1793 } // 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
This is Rietveld 408576698