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

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. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 String* script_name = script->name()->IsString() 398 String* script_name = script->name()->IsString()
399 ? String::cast(script->name()) 399 ? String::cast(script->name())
400 : info->isolate()->heap()->empty_string(); 400 : info->isolate()->heap()->empty_string();
401 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script); 401 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script);
402 PROFILE(info->isolate(), 402 PROFILE(info->isolate(),
403 CodeCreateEvent(log_tag, *abstract_code, *shared, info, script_name, 403 CodeCreateEvent(log_tag, *abstract_code, *shared, info, script_name,
404 line_num, column_num)); 404 line_num, column_num));
405 } 405 }
406 } 406 }
407 407
408 void EnsureFeedbackVector(CompilationInfo* info) { 408 void EnsureFeedbackMetadata(CompilationInfo* info) {
409 DCHECK(info->has_shared_info()); 409 DCHECK(info->has_shared_info());
410 410
411 // If no type feedback vector exists, we create one now. At this point the 411 // If no type feedback metadata exists, we create it now. At this point the
412 // AstNumbering pass has already run. Note the snapshot can contain outdated 412 // AstNumbering pass has already run. Note the snapshot can contain outdated
413 // vectors for a different configuration, hence we also recreate a new vector 413 // vectors for a different configuration, hence we also recreate a new vector
414 // when the function is not compiled (i.e. no code was serialized). 414 // when the function is not compiled (i.e. no code was serialized).
415 if (info->shared_info()->feedback_vector()->is_empty() || 415
416 // TODO(mvstanton): reintroduce is_empty() predicate to feedback_metadata().
417 if (info->shared_info()->feedback_metadata()->length() == 0 ||
416 !info->shared_info()->is_compiled()) { 418 !info->shared_info()->is_compiled()) {
417 Handle<TypeFeedbackMetadata> feedback_metadata = TypeFeedbackMetadata::New( 419 Handle<TypeFeedbackMetadata> feedback_metadata = TypeFeedbackMetadata::New(
418 info->isolate(), info->literal()->feedback_vector_spec()); 420 info->isolate(), info->literal()->feedback_vector_spec());
419 Handle<TypeFeedbackVector> feedback_vector = 421 info->shared_info()->set_feedback_metadata(*feedback_metadata);
420 TypeFeedbackVector::New(info->isolate(), feedback_metadata);
421 info->shared_info()->set_feedback_vector(*feedback_vector);
422 } 422 }
423 423
424 // It's very important that recompiles do not alter the structure of the type 424 // It's very important that recompiles do not alter the structure of the type
425 // feedback vector. Verify that the structure fits the function literal. 425 // feedback vector. Verify that the structure fits the function literal.
426 CHECK(!info->shared_info()->feedback_vector()->metadata()->SpecDiffersFrom( 426 CHECK(!info->shared_info()->feedback_metadata()->SpecDiffersFrom(
427 info->literal()->feedback_vector_spec())); 427 info->literal()->feedback_vector_spec()));
428 } 428 }
429 429
430 bool UseIgnition(CompilationInfo* info) { 430 bool UseIgnition(CompilationInfo* info) {
431 if (info->is_debug()) return false; 431 if (info->is_debug()) return false;
432 if (info->shared_info()->is_generator() && !FLAG_ignition_generators) { 432 if (info->shared_info()->is_generator() && !FLAG_ignition_generators) {
433 return false; 433 return false;
434 } 434 }
435 435
436 // Checks whether top level functions should be passed by the filter. 436 // Checks whether top level functions should be passed by the filter.
(...skipping 19 matching lines...) Expand all
456 size += code->CodeSize(); 456 size += code->CodeSize();
457 size += code->relocation_info()->Size(); 457 size += code->relocation_info()->Size();
458 size += code->deoptimization_data()->Size(); 458 size += code->deoptimization_data()->Size();
459 size += code->handler_table()->Size(); 459 size += code->handler_table()->Size();
460 } 460 }
461 return size; 461 return size;
462 } 462 }
463 463
464 bool GenerateUnoptimizedCode(CompilationInfo* info) { 464 bool GenerateUnoptimizedCode(CompilationInfo* info) {
465 bool success; 465 bool success;
466 EnsureFeedbackVector(info); 466 EnsureFeedbackMetadata(info);
467 if (FLAG_ignition && UseIgnition(info)) { 467 if (FLAG_ignition && UseIgnition(info)) {
468 success = interpreter::Interpreter::MakeBytecode(info); 468 success = interpreter::Interpreter::MakeBytecode(info);
469 } else { 469 } else {
470 success = FullCodeGenerator::MakeCode(info); 470 success = FullCodeGenerator::MakeCode(info);
471 } 471 }
472 if (success) { 472 if (success) {
473 Isolate* isolate = info->isolate(); 473 Isolate* isolate = info->isolate();
474 Counters* counters = isolate->counters(); 474 Counters* counters = isolate->counters();
475 // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually. 475 // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually.
476 counters->total_baseline_code_size()->Increment(CodeAndMetadataSize(info)); 476 counters->total_baseline_code_size()->Increment(CodeAndMetadataSize(info));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 } 509 }
510 } 510 }
511 511
512 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { 512 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) {
513 VMState<COMPILER> state(info->isolate()); 513 VMState<COMPILER> state(info->isolate());
514 PostponeInterruptsScope postpone(info->isolate()); 514 PostponeInterruptsScope postpone(info->isolate());
515 515
516 // Parse and update CompilationInfo with the results. 516 // Parse and update CompilationInfo with the results.
517 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); 517 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>();
518 Handle<SharedFunctionInfo> shared = info->shared_info(); 518 Handle<SharedFunctionInfo> shared = info->shared_info();
519 DCHECK_EQ(shared->language_mode(), info->literal()->language_mode()); 519
520 // TODO(mvstanton): can I eliminate this? MStarzinger got rid of this
521 // boilerplate stuff before.
522 FunctionLiteral* lit = info->literal();
523 DCHECK_EQ(shared->language_mode(), lit->language_mode());
524 shared->set_num_literals(lit->materialized_literal_count());
Michael Starzinger 2016/05/10 13:47:20 Depending on who computes the literals count for a
mvstanton 2016/05/24 16:31:49 Happily, I could eliminate this piece completely (
520 525
521 // Compile either unoptimized code or bytecode for the interpreter. 526 // Compile either unoptimized code or bytecode for the interpreter.
522 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); 527 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>();
523 528
524 // Update the shared function info with the scope info. 529 // Update the shared function info with the scope info.
525 InstallSharedScopeInfo(info, shared); 530 InstallSharedScopeInfo(info, shared);
526 531
527 // Install compilation result on the shared function info 532 // Install compilation result on the shared function info
528 InstallSharedCompilationResult(info, shared); 533 InstallSharedCompilationResult(info, shared);
529 534
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 632
628 bool GetOptimizedCodeNow(CompilationJob* job) { 633 bool GetOptimizedCodeNow(CompilationJob* job) {
629 CompilationInfo* info = job->info(); 634 CompilationInfo* info = job->info();
630 Isolate* isolate = info->isolate(); 635 Isolate* isolate = info->isolate();
631 636
632 // Parsing is not required when optimizing from existing bytecode. 637 // Parsing is not required when optimizing from existing bytecode.
633 if (!info->is_optimizing_from_bytecode()) { 638 if (!info->is_optimizing_from_bytecode()) {
634 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; 639 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false;
635 } 640 }
636 641
642 EnsureFeedbackMetadata(info);
643 JSFunction::EnsureLiterals(info->closure());
644
637 TimerEventScope<TimerEventRecompileSynchronous> timer(isolate); 645 TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
638 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); 646 TRACE_EVENT0("v8", "V8.RecompileSynchronous");
639 647
640 if (job->CreateGraph() != CompilationJob::SUCCEEDED || 648 if (job->CreateGraph() != CompilationJob::SUCCEEDED ||
641 job->OptimizeGraph() != CompilationJob::SUCCEEDED || 649 job->OptimizeGraph() != CompilationJob::SUCCEEDED ||
642 job->GenerateCode() != CompilationJob::SUCCEEDED) { 650 job->GenerateCode() != CompilationJob::SUCCEEDED) {
643 if (FLAG_trace_opt) { 651 if (FLAG_trace_opt) {
644 PrintF("[aborted optimizing "); 652 PrintF("[aborted optimizing ");
645 info->closure()->ShortPrint(); 653 info->closure()->ShortPrint();
646 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); 654 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason()));
(...skipping 24 matching lines...) Expand all
671 679
672 // All handles below this point will be allocated in a deferred handle scope 680 // All handles below this point will be allocated in a deferred handle scope
673 // that is detached and handed off to the background thread when we return. 681 // that is detached and handed off to the background thread when we return.
674 CompilationHandleScope handle_scope(info); 682 CompilationHandleScope handle_scope(info);
675 683
676 // Parsing is not required when optimizing from existing bytecode. 684 // Parsing is not required when optimizing from existing bytecode.
677 if (!info->is_optimizing_from_bytecode()) { 685 if (!info->is_optimizing_from_bytecode()) {
678 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; 686 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false;
679 } 687 }
680 688
689 JSFunction::EnsureLiterals(info->closure());
690
681 // Reopen handles in the new CompilationHandleScope. 691 // Reopen handles in the new CompilationHandleScope.
682 info->ReopenHandlesInNewHandleScope(); 692 info->ReopenHandlesInNewHandleScope();
683 info->parse_info()->ReopenHandlesInNewHandleScope(); 693 info->parse_info()->ReopenHandlesInNewHandleScope();
684 694
685 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); 695 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate());
686 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); 696 TRACE_EVENT0("v8", "V8.RecompileSynchronous");
687 697
688 if (job->CreateGraph() != CompilationJob::SUCCEEDED) return false; 698 if (job->CreateGraph() != CompilationJob::SUCCEEDED) return false;
689 isolate->optimizing_compile_dispatcher()->QueueForOptimization(job); 699 isolate->optimizing_compile_dispatcher()->QueueForOptimization(job);
690 700
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 Handle<Code> code; 1126 Handle<Code> code;
1117 if (!GetLazyCode(function).ToHandle(&code)) { 1127 if (!GetLazyCode(function).ToHandle(&code)) {
1118 if (flag == CLEAR_EXCEPTION) { 1128 if (flag == CLEAR_EXCEPTION) {
1119 isolate->clear_pending_exception(); 1129 isolate->clear_pending_exception();
1120 } 1130 }
1121 return false; 1131 return false;
1122 } 1132 }
1123 1133
1124 // Install code on closure. 1134 // Install code on closure.
1125 function->ReplaceCode(*code); 1135 function->ReplaceCode(*code);
1136 JSFunction::EnsureLiterals(function);
1126 1137
1127 // Check postconditions on success. 1138 // Check postconditions on success.
1128 DCHECK(!isolate->has_pending_exception()); 1139 DCHECK(!isolate->has_pending_exception());
1129 DCHECK(function->shared()->is_compiled()); 1140 DCHECK(function->shared()->is_compiled());
1130 DCHECK(function->is_compiled()); 1141 DCHECK(function->is_compiled());
1131 return true; 1142 return true;
1132 } 1143 }
1133 1144
1134 bool Compiler::CompileBaseline(Handle<JSFunction> function) { 1145 bool Compiler::CompileBaseline(Handle<JSFunction> function) {
1135 Isolate* isolate = function->GetIsolate(); 1146 Isolate* isolate = function->GetIsolate();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 ParseInfo parse_info(&zone, function); 1183 ParseInfo parse_info(&zone, function);
1173 CompilationInfo info(&parse_info, function); 1184 CompilationInfo info(&parse_info, function);
1174 if (!GetUnoptimizedCode(&info).ToHandle(&code)) { 1185 if (!GetUnoptimizedCode(&info).ToHandle(&code)) {
1175 return false; 1186 return false;
1176 } 1187 }
1177 } 1188 }
1178 } 1189 }
1179 1190
1180 // Install code on closure. 1191 // Install code on closure.
1181 function->ReplaceCode(*code); 1192 function->ReplaceCode(*code);
1193 JSFunction::EnsureLiterals(function);
1182 1194
1183 // Check postconditions on success. 1195 // Check postconditions on success.
1184 DCHECK(!isolate->has_pending_exception()); 1196 DCHECK(!isolate->has_pending_exception());
1185 DCHECK(function->shared()->is_compiled()); 1197 DCHECK(function->shared()->is_compiled());
1186 DCHECK(function->is_compiled()); 1198 DCHECK(function->is_compiled());
1187 return true; 1199 return true;
1188 } 1200 }
1189 1201
1190 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { 1202 bool Compiler::CompileDebugCode(Handle<JSFunction> function) {
1191 Isolate* isolate = function->GetIsolate(); 1203 Isolate* isolate = function->GetIsolate();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 HasInterpreterActivations(info->isolate(), *shared)) { 1290 HasInterpreterActivations(info->isolate(), *shared)) {
1279 return false; 1291 return false;
1280 } 1292 }
1281 // If the current code has reloc info for serialization, also include 1293 // If the current code has reloc info for serialization, also include
1282 // reloc info for serialization for the new code, so that deopt support 1294 // reloc info for serialization for the new code, so that deopt support
1283 // can be added without losing IC state. 1295 // can be added without losing IC state.
1284 if (shared->code()->kind() == Code::FUNCTION && 1296 if (shared->code()->kind() == Code::FUNCTION &&
1285 shared->code()->has_reloc_info_for_serialization()) { 1297 shared->code()->has_reloc_info_for_serialization()) {
1286 unoptimized.PrepareForSerializing(); 1298 unoptimized.PrepareForSerializing();
1287 } 1299 }
1288 EnsureFeedbackVector(&unoptimized); 1300 EnsureFeedbackMetadata(&unoptimized);
1289 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; 1301 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false;
1290 1302
1291 // TODO(4280): For now we play it safe and remove the bytecode array when we 1303 // TODO(4280): For now we play it safe and remove the bytecode array when we
1292 // switch to baseline code. We might consider keeping around the bytecode so 1304 // switch to baseline code. We might consider keeping around the bytecode so
1293 // that it can be used as the "source of truth" eventually. 1305 // that it can be used as the "source of truth" eventually.
1294 shared->ClearBytecodeArray(); 1306 shared->ClearBytecodeArray();
1295 1307
1296 // The scope info might not have been set if a lazily compiled 1308 // The scope info might not have been set if a lazily compiled
1297 // function is inlined before being called for the first time. 1309 // function is inlined before being called for the first time.
1298 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { 1310 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) {
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
1653 Handle<JSFunction> fun = Handle<JSFunction>::cast(Utils::OpenHandle( 1665 Handle<JSFunction> fun = Handle<JSFunction>::cast(Utils::OpenHandle(
1654 *fun_template->GetFunction(v8_isolate->GetCurrentContext()) 1666 *fun_template->GetFunction(v8_isolate->GetCurrentContext())
1655 .ToLocalChecked())); 1667 .ToLocalChecked()));
1656 const int literals = fun->NumberOfLiterals(); 1668 const int literals = fun->NumberOfLiterals();
1657 Handle<Code> code = Handle<Code>(fun->shared()->code()); 1669 Handle<Code> code = Handle<Code>(fun->shared()->code());
1658 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); 1670 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
1659 Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( 1671 Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo(
1660 name, literals, FunctionKind::kNormalFunction, code, 1672 name, literals, FunctionKind::kNormalFunction, code,
1661 Handle<ScopeInfo>(fun->shared()->scope_info())); 1673 Handle<ScopeInfo>(fun->shared()->scope_info()));
1662 shared->set_construct_stub(*construct_stub); 1674 shared->set_construct_stub(*construct_stub);
1663 shared->set_feedback_vector(fun->shared()->feedback_vector()); 1675 shared->set_feedback_metadata(fun->shared()->feedback_metadata());
1664 1676
1665 // Copy the function data to the shared function info. 1677 // Copy the function data to the shared function info.
1666 shared->set_function_data(fun->shared()->function_data()); 1678 shared->set_function_data(fun->shared()->function_data());
1667 int parameters = fun->shared()->internal_formal_parameter_count(); 1679 int parameters = fun->shared()->internal_formal_parameter_count();
1668 shared->set_internal_formal_parameter_count(parameters); 1680 shared->set_internal_formal_parameter_count(parameters);
1669 1681
1670 return shared; 1682 return shared;
1671 } 1683 }
1672 1684
1673 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, 1685 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1740 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( 1752 CodeAndLiterals cached = shared->SearchOptimizedCodeMap(
1741 function->context()->native_context(), BailoutId::None()); 1753 function->context()->native_context(), BailoutId::None());
1742 if (cached.code != nullptr) { 1754 if (cached.code != nullptr) {
1743 // Caching of optimized code enabled and optimized code found. 1755 // Caching of optimized code enabled and optimized code found.
1744 DCHECK(!cached.code->marked_for_deoptimization()); 1756 DCHECK(!cached.code->marked_for_deoptimization());
1745 DCHECK(function->shared()->is_compiled()); 1757 DCHECK(function->shared()->is_compiled());
1746 function->ReplaceCode(cached.code); 1758 function->ReplaceCode(cached.code);
1747 } 1759 }
1748 1760
1749 if (cached.literals != nullptr) { 1761 if (cached.literals != nullptr) {
1762 DCHECK(shared->is_compiled());
1750 function->set_literals(cached.literals); 1763 function->set_literals(cached.literals);
1751 } else { 1764 } else if (shared->is_compiled()) {
1752 Isolate* isolate = function->GetIsolate(); 1765 // TODO(mvstanton): pass pretenure flag to EnsureLiterals.
1753 int number_of_literals = shared->num_literals(); 1766 JSFunction::EnsureLiterals(function);
1754 Handle<LiteralsArray> literals =
1755 LiteralsArray::New(isolate, handle(shared->feedback_vector()),
1756 number_of_literals, pretenure);
1757 function->set_literals(*literals);
1758
1759 // Cache context-specific literals.
1760 MaybeHandle<Code> code;
1761 if (cached.code != nullptr) code = handle(cached.code);
1762 Handle<Context> native_context(function->context()->native_context());
1763 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code,
1764 literals, BailoutId::None());
1765 } 1767 }
1766 } 1768 }
1767 1769
1768 } // namespace internal 1770 } // namespace internal
1769 } // namespace v8 1771 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698