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

Side by Side Diff: src/compiler.cc

Issue 1525663002: [interpreter] Unify decision how to compile baseline code. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Back out widening of intake valve. Created 5 years 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 | « no previous file | no next file » | 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 688 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 if (!isolate->has_pending_exception()) isolate->StackOverflow(); 699 if (!isolate->has_pending_exception()) isolate->StackOverflow();
700 return false; 700 return false;
701 } 701 }
702 return true; 702 return true;
703 } 703 }
704 704
705 705
706 // TODO(rmcilroy): Remove this temporary work-around when ignition supports 706 // TODO(rmcilroy): Remove this temporary work-around when ignition supports
707 // catch and eval. 707 // catch and eval.
708 static bool IgnitionShouldFallbackToFullCodeGen(Scope* scope) { 708 static bool IgnitionShouldFallbackToFullCodeGen(Scope* scope) {
709 if (!FLAG_ignition_fallback_on_eval_and_catch) return false;
710
711 if (scope->is_eval_scope() || scope->is_catch_scope() || 709 if (scope->is_eval_scope() || scope->is_catch_scope() ||
712 scope->calls_eval()) { 710 scope->calls_eval()) {
713 return true; 711 return true;
714 } 712 }
715 for (auto inner_scope : *scope->inner_scopes()) { 713 for (auto inner_scope : *scope->inner_scopes()) {
716 if (IgnitionShouldFallbackToFullCodeGen(inner_scope)) return true; 714 if (IgnitionShouldFallbackToFullCodeGen(inner_scope)) return true;
717 } 715 }
718 return false; 716 return false;
719 } 717 }
720 718
721 719
722 static bool GenerateBytecode(CompilationInfo* info) { 720 static bool UseIgnition(CompilationInfo* info) {
723 DCHECK(AllowCompilation::IsAllowed(info->isolate())); 721 // Cannot use Ignition when the {function_data} is already used.
724 bool success = false; 722 if (info->has_shared_info() && info->shared_info()->HasBuiltinFunctionId()) {
725 if (Compiler::Analyze(info->parse_info())) { 723 return false;
726 if (IgnitionShouldFallbackToFullCodeGen(info->scope())) {
727 success = FullCodeGenerator::MakeCode(info);
728 } else {
729 success = interpreter::Interpreter::MakeBytecode(info);
730 }
731 } 724 }
732 if (!success) { 725
733 Isolate* isolate = info->isolate(); 726 // Checks whether the scope chain is supported.
734 if (!isolate->has_pending_exception()) isolate->StackOverflow(); 727 if (FLAG_ignition_fallback_on_eval_and_catch &&
728 IgnitionShouldFallbackToFullCodeGen(info->scope())) {
729 return false;
735 } 730 }
736 return success; 731
732 // Checks whether top level functions should be passed by the filter.
733 if (info->closure().is_null()) {
734 Vector<const char> filter = CStrVector(FLAG_ignition_filter);
735 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*');
736 }
737
738 // Finally respect the filter.
739 return info->closure()->PassesFilter(FLAG_ignition_filter);
737 } 740 }
738 741
739 742
743 static bool GenerateBaselineCode(CompilationInfo* info) {
744 if (FLAG_ignition && UseIgnition(info)) {
745 return interpreter::Interpreter::MakeBytecode(info);
746 } else {
747 return FullCodeGenerator::MakeCode(info);
748 }
749 }
750
751
752 static bool CompileBaselineCode(CompilationInfo* info) {
753 DCHECK(AllowCompilation::IsAllowed(info->isolate()));
754 if (!Compiler::Analyze(info->parse_info()) || !GenerateBaselineCode(info)) {
755 Isolate* isolate = info->isolate();
756 if (!isolate->has_pending_exception()) isolate->StackOverflow();
757 return false;
758 }
759 return true;
760 }
761
762
740 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( 763 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon(
741 CompilationInfo* info) { 764 CompilationInfo* info) {
742 VMState<COMPILER> state(info->isolate()); 765 VMState<COMPILER> state(info->isolate());
743 PostponeInterruptsScope postpone(info->isolate()); 766 PostponeInterruptsScope postpone(info->isolate());
744 767
745 // Parse and update CompilationInfo with the results. 768 // Parse and update CompilationInfo with the results.
746 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); 769 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>();
747 Handle<SharedFunctionInfo> shared = info->shared_info(); 770 Handle<SharedFunctionInfo> shared = info->shared_info();
748 FunctionLiteral* lit = info->literal(); 771 FunctionLiteral* lit = info->literal();
749 DCHECK_EQ(shared->language_mode(), lit->language_mode()); 772 DCHECK_EQ(shared->language_mode(), lit->language_mode());
750 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); 773 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
751 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); 774 MaybeDisableOptimization(shared, lit->dont_optimize_reason());
752 775
753 if (FLAG_ignition && !shared->HasBuiltinFunctionId() && 776 // Compile either unoptimized code or bytecode for the interpreter.
754 info->closure()->PassesFilter(FLAG_ignition_filter)) { 777 if (!CompileBaselineCode(info)) return MaybeHandle<Code>();
755 // Compile bytecode for the interpreter. 778 if (info->code()->kind() == Code::FUNCTION) { // Only for full code.
756 if (!GenerateBytecode(info)) return MaybeHandle<Code>();
757 } else {
758 // Compile unoptimized code.
759 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>();
760
761 CHECK_EQ(Code::FUNCTION, info->code()->kind());
762 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); 779 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
763 } 780 }
764 781
765 // Update the shared function info with the scope info. Allocating the 782 // Update the shared function info with the scope info. Allocating the
766 // ScopeInfo object may cause a GC. 783 // ScopeInfo object may cause a GC.
767 Handle<ScopeInfo> scope_info = 784 Handle<ScopeInfo> scope_info =
768 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); 785 ScopeInfo::Create(info->isolate(), info->zone(), info->scope());
769 shared->set_scope_info(*scope_info); 786 shared->set_scope_info(*scope_info);
770 787
771 // Update the code and feedback vector for the shared function info. 788 // Update the code and feedback vector for the shared function info.
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 if (!CompileUnoptimizedCode(&info)) return; 1187 if (!CompileUnoptimizedCode(&info)) return;
1171 if (info.has_shared_info()) { 1188 if (info.has_shared_info()) {
1172 Handle<ScopeInfo> scope_info = 1189 Handle<ScopeInfo> scope_info =
1173 ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); 1190 ScopeInfo::Create(info.isolate(), info.zone(), info.scope());
1174 info.shared_info()->set_scope_info(*scope_info); 1191 info.shared_info()->set_scope_info(*scope_info);
1175 } 1192 }
1176 tracker.RecordRootFunctionInfo(info.code()); 1193 tracker.RecordRootFunctionInfo(info.code());
1177 } 1194 }
1178 1195
1179 1196
1180 // Checks whether top level functions should be passed by {raw_filter}.
1181 static bool TopLevelFunctionPassesFilter(const char* raw_filter) {
1182 Vector<const char> filter = CStrVector(raw_filter);
1183 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*');
1184 }
1185
1186
1187 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { 1197 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
1188 Isolate* isolate = info->isolate(); 1198 Isolate* isolate = info->isolate();
1189 PostponeInterruptsScope postpone(isolate); 1199 PostponeInterruptsScope postpone(isolate);
1190 DCHECK(!isolate->native_context().is_null()); 1200 DCHECK(!isolate->native_context().is_null());
1191 ParseInfo* parse_info = info->parse_info(); 1201 ParseInfo* parse_info = info->parse_info();
1192 Handle<Script> script = parse_info->script(); 1202 Handle<Script> script = parse_info->script();
1193 1203
1194 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? 1204 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile?
1195 FixedArray* array = isolate->native_context()->embedder_data(); 1205 FixedArray* array = isolate->native_context()->embedder_data();
1196 script->set_context_data(array->get(v8::Context::kDebugIdIndex)); 1206 script->set_context_data(array->get(v8::Context::kDebugIdIndex));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 1250
1241 // Measure how long it takes to do the compilation; only take the 1251 // Measure how long it takes to do the compilation; only take the
1242 // rest of the function into account to avoid overlap with the 1252 // rest of the function into account to avoid overlap with the
1243 // parsing statistics. 1253 // parsing statistics.
1244 HistogramTimer* rate = info->is_eval() 1254 HistogramTimer* rate = info->is_eval()
1245 ? info->isolate()->counters()->compile_eval() 1255 ? info->isolate()->counters()->compile_eval()
1246 : info->isolate()->counters()->compile(); 1256 : info->isolate()->counters()->compile();
1247 HistogramTimerScope timer(rate); 1257 HistogramTimerScope timer(rate);
1248 1258
1249 // Compile the code. 1259 // Compile the code.
1250 if (FLAG_ignition && TopLevelFunctionPassesFilter(FLAG_ignition_filter)) { 1260 if (!CompileBaselineCode(info)) {
1251 if (!GenerateBytecode(info)) { 1261 return Handle<SharedFunctionInfo>::null();
1252 return Handle<SharedFunctionInfo>::null();
1253 }
1254 } else {
1255 if (!CompileUnoptimizedCode(info)) {
1256 return Handle<SharedFunctionInfo>::null();
1257 }
1258 } 1262 }
1259 1263
1260 // Allocate function. 1264 // Allocate function.
1261 DCHECK(!info->code().is_null()); 1265 DCHECK(!info->code().is_null());
1262 result = isolate->factory()->NewSharedFunctionInfo( 1266 result = isolate->factory()->NewSharedFunctionInfo(
1263 lit->name(), lit->materialized_literal_count(), lit->kind(), 1267 lit->name(), lit->materialized_literal_count(), lit->kind(),
1264 info->code(), 1268 info->code(),
1265 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), 1269 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()),
1266 info->feedback_vector()); 1270 info->feedback_vector());
1267 if (info->has_bytecode_array()) { 1271 if (info->has_bytecode_array()) {
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
1594 // feedback vector, but some parts of the system expect all 1598 // feedback vector, but some parts of the system expect all
1595 // SharedFunctionInfo instances to have one. The size of the vector depends 1599 // SharedFunctionInfo instances to have one. The size of the vector depends
1596 // on how many feedback-needing nodes are in the tree, and when lazily 1600 // on how many feedback-needing nodes are in the tree, and when lazily
1597 // parsing we might not know that, if this function was never parsed before. 1601 // parsing we might not know that, if this function was never parsed before.
1598 // In that case the vector will be replaced the next time MakeCode is 1602 // In that case the vector will be replaced the next time MakeCode is
1599 // called. 1603 // called.
1600 info.EnsureFeedbackVector(); 1604 info.EnsureFeedbackVector();
1601 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); 1605 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate));
1602 } else if (Renumber(info.parse_info()) && 1606 } else if (Renumber(info.parse_info()) &&
1603 FullCodeGenerator::MakeCode(&info)) { 1607 FullCodeGenerator::MakeCode(&info)) {
1604 // MakeCode will ensure that the feedback vector is present and 1608 // Code generation will ensure that the feedback vector is present and
1605 // appropriately sized. 1609 // appropriately sized.
1606 DCHECK(!info.code().is_null()); 1610 DCHECK(!info.code().is_null());
1607 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); 1611 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope());
1608 if (literal->should_eager_compile() && 1612 if (literal->should_eager_compile() &&
1609 literal->should_be_used_once_hint()) { 1613 literal->should_be_used_once_hint()) {
1610 info.code()->MarkToBeExecutedOnce(isolate); 1614 info.code()->MarkToBeExecutedOnce(isolate);
1611 } 1615 }
1612 } else { 1616 } else {
1613 return Handle<SharedFunctionInfo>::null(); 1617 return Handle<SharedFunctionInfo>::null();
1614 } 1618 }
1615 1619
1616 if (maybe_existing.is_null()) { 1620 if (maybe_existing.is_null()) {
1617 // Create a shared function info object. 1621 // Create a shared function info object.
1618 Handle<SharedFunctionInfo> result = 1622 Handle<SharedFunctionInfo> result =
1619 isolate->factory()->NewSharedFunctionInfo( 1623 isolate->factory()->NewSharedFunctionInfo(
1620 literal->name(), literal->materialized_literal_count(), 1624 literal->name(), literal->materialized_literal_count(),
1621 literal->kind(), info.code(), scope_info, info.feedback_vector()); 1625 literal->kind(), info.code(), scope_info, info.feedback_vector());
1626 if (info.has_bytecode_array()) {
1627 DCHECK(result->function_data()->IsUndefined());
1628 result->set_function_data(*info.bytecode_array());
1629 }
1622 1630
1623 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); 1631 SharedFunctionInfo::InitFromFunctionLiteral(result, literal);
1624 SharedFunctionInfo::SetScript(result, script); 1632 SharedFunctionInfo::SetScript(result, script);
1625 result->set_is_toplevel(false); 1633 result->set_is_toplevel(false);
1626 // If the outer function has been compiled before, we cannot be sure that 1634 // If the outer function has been compiled before, we cannot be sure that
1627 // shared function info for this function literal has been created for the 1635 // shared function info for this function literal has been created for the
1628 // first time. It may have already been compiled previously. 1636 // first time. It may have already been compiled previously.
1629 result->set_never_compiled(outer_info->is_first_compile() && lazy); 1637 result->set_never_compiled(outer_info->is_first_compile() && lazy);
1630 1638
1631 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); 1639 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1803 } 1811 }
1804 1812
1805 #if DEBUG 1813 #if DEBUG
1806 void CompilationInfo::PrintAstForTesting() { 1814 void CompilationInfo::PrintAstForTesting() {
1807 PrintF("--- Source from AST ---\n%s\n", 1815 PrintF("--- Source from AST ---\n%s\n",
1808 PrettyPrinter(isolate()).PrintProgram(literal())); 1816 PrettyPrinter(isolate()).PrintProgram(literal()));
1809 } 1817 }
1810 #endif 1818 #endif
1811 } // namespace internal 1819 } // namespace internal
1812 } // namespace v8 1820 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698