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-numbering.h" | 9 #include "src/ast-numbering.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 674 matching lines...) Loading... | |
685 ? String::cast(script->name()) | 685 ? String::cast(script->name()) |
686 : info->isolate()->heap()->empty_string(); | 686 : info->isolate()->heap()->empty_string(); |
687 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script); | 687 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script); |
688 PROFILE(info->isolate(), | 688 PROFILE(info->isolate(), |
689 CodeCreateEvent(log_tag, *code, *shared, info, script_name, | 689 CodeCreateEvent(log_tag, *code, *shared, info, script_name, |
690 line_num, column_num)); | 690 line_num, column_num)); |
691 } | 691 } |
692 } | 692 } |
693 | 693 |
694 | 694 |
695 // Checks whether top level functions should be passed by {raw_filter}. | |
696 // TODO(rmcilroy): Remove filtering once ignition can handle test262 harness. | |
697 static bool TopLevelFunctionPassesFilter(const char* raw_filter) { | |
698 Vector<const char> filter = CStrVector(raw_filter); | |
699 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); | |
700 } | |
701 | |
702 | |
703 // Checks whether the passed {raw_filter} is a prefix of the given scripts name. | |
704 // TODO(rmcilroy): Remove filtering once ignition can handle test262 harness. | |
705 static bool ScriptPassesFilter(const char* raw_filter, Handle<Script> script) { | |
706 Vector<const char> filter = CStrVector(raw_filter); | |
707 if (!script->name()->IsString()) return filter.length() == 0; | |
708 String* name = String::cast(script->name()); | |
709 return name->IsUtf8EqualTo(filter, true); | |
710 } | |
711 | |
712 | |
713 static bool CompileUnoptimizedCode(CompilationInfo* info) { | 695 static bool CompileUnoptimizedCode(CompilationInfo* info) { |
714 DCHECK(AllowCompilation::IsAllowed(info->isolate())); | 696 DCHECK(AllowCompilation::IsAllowed(info->isolate())); |
715 if (!Compiler::Analyze(info->parse_info()) || | 697 if (!Compiler::Analyze(info->parse_info()) || |
716 !FullCodeGenerator::MakeCode(info)) { | 698 !FullCodeGenerator::MakeCode(info)) { |
717 Isolate* isolate = info->isolate(); | 699 Isolate* isolate = info->isolate(); |
718 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 700 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
719 return false; | 701 return false; |
720 } | 702 } |
721 return true; | 703 return true; |
722 } | 704 } |
723 | 705 |
724 | 706 |
707 // Checks whether top level functions should be passed by {raw_filter}. | |
708 static bool TopLevelFunctionPassesFilter(const char* raw_filter) { | |
Michael Starzinger
2015/11/05 18:21:43
nit: Same comment as below, I assume this is tempo
rmcilroy
2015/11/06 09:51:14
The one below is temporary, however this one I thi
Michael Starzinger
2015/11/06 10:06:30
Acknowledged. You are right, makes sense. Can we m
rmcilroy
2015/11/06 10:50:19
Move above CompileTopLevel since that is where it'
Michael Starzinger
2015/11/06 10:51:42
Acknowledged. Even better! :)
| |
709 Vector<const char> filter = CStrVector(raw_filter); | |
710 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); | |
711 } | |
712 | |
713 | |
714 static bool IgnitionShouldFallbackToFullCodeGen(Scope* scope) { | |
Michael Starzinger
2015/11/05 18:21:43
nit: Can we add a TODO here saying that this is a
rmcilroy
2015/11/06 09:51:14
Done.
| |
715 if (!FLAG_ignition_fallback_on_eval_and_catch) return false; | |
716 | |
717 if (scope->is_eval_scope() || scope->is_catch_scope() || | |
718 scope->calls_eval()) { | |
719 return true; | |
720 } | |
721 for (auto inner_scope : *scope->inner_scopes()) { | |
722 if (IgnitionShouldFallbackToFullCodeGen(inner_scope)) return true; | |
723 } | |
724 return false; | |
725 } | |
726 | |
727 | |
725 static bool GenerateBytecode(CompilationInfo* info) { | 728 static bool GenerateBytecode(CompilationInfo* info) { |
726 DCHECK(AllowCompilation::IsAllowed(info->isolate())); | 729 DCHECK(AllowCompilation::IsAllowed(info->isolate())); |
727 if (!Compiler::Analyze(info->parse_info()) || | 730 bool success = false; |
728 !interpreter::Interpreter::MakeBytecode(info)) { | 731 if (Compiler::Analyze(info->parse_info())) { |
732 if (IgnitionShouldFallbackToFullCodeGen(info->scope())) { | |
733 success = FullCodeGenerator::MakeCode(info); | |
734 } else { | |
735 success = interpreter::Interpreter::MakeBytecode(info); | |
736 } | |
737 } | |
738 if (!success) { | |
729 Isolate* isolate = info->isolate(); | 739 Isolate* isolate = info->isolate(); |
730 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 740 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
731 return false; | |
732 } | 741 } |
733 return true; | 742 return success; |
734 } | 743 } |
735 | 744 |
736 | 745 |
737 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( | 746 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( |
738 CompilationInfo* info) { | 747 CompilationInfo* info) { |
739 VMState<COMPILER> state(info->isolate()); | 748 VMState<COMPILER> state(info->isolate()); |
740 PostponeInterruptsScope postpone(info->isolate()); | 749 PostponeInterruptsScope postpone(info->isolate()); |
741 | 750 |
742 // Parse and update CompilationInfo with the results. | 751 // Parse and update CompilationInfo with the results. |
743 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); | 752 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); |
744 Handle<SharedFunctionInfo> shared = info->shared_info(); | 753 Handle<SharedFunctionInfo> shared = info->shared_info(); |
745 FunctionLiteral* lit = info->literal(); | 754 FunctionLiteral* lit = info->literal(); |
746 shared->set_language_mode(lit->language_mode()); | 755 shared->set_language_mode(lit->language_mode()); |
747 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); | 756 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); |
748 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); | 757 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); |
749 | 758 |
750 if (FLAG_ignition && !shared->HasBuiltinFunctionId() && | 759 if (FLAG_ignition && !shared->HasBuiltinFunctionId() && |
751 info->closure()->PassesFilter(FLAG_ignition_filter) && | 760 info->closure()->PassesFilter(FLAG_ignition_filter)) { |
752 ScriptPassesFilter(FLAG_ignition_script_filter, info->script())) { | |
753 // Compile bytecode for the interpreter. | 761 // Compile bytecode for the interpreter. |
754 if (!GenerateBytecode(info)) return MaybeHandle<Code>(); | 762 if (!GenerateBytecode(info)) return MaybeHandle<Code>(); |
755 } else { | 763 } else { |
756 // Compile unoptimized code. | 764 // Compile unoptimized code. |
757 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); | 765 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
758 | 766 |
759 CHECK_EQ(Code::FUNCTION, info->code()->kind()); | 767 CHECK_EQ(Code::FUNCTION, info->code()->kind()); |
760 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); | 768 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); |
761 } | 769 } |
762 | 770 |
(...skipping 467 matching lines...) Loading... | |
1230 | 1238 |
1231 // Measure how long it takes to do the compilation; only take the | 1239 // Measure how long it takes to do the compilation; only take the |
1232 // rest of the function into account to avoid overlap with the | 1240 // rest of the function into account to avoid overlap with the |
1233 // parsing statistics. | 1241 // parsing statistics. |
1234 HistogramTimer* rate = info->is_eval() | 1242 HistogramTimer* rate = info->is_eval() |
1235 ? info->isolate()->counters()->compile_eval() | 1243 ? info->isolate()->counters()->compile_eval() |
1236 : info->isolate()->counters()->compile(); | 1244 : info->isolate()->counters()->compile(); |
1237 HistogramTimerScope timer(rate); | 1245 HistogramTimerScope timer(rate); |
1238 | 1246 |
1239 // Compile the code. | 1247 // Compile the code. |
1240 if (FLAG_ignition && TopLevelFunctionPassesFilter(FLAG_ignition_filter) && | 1248 if (FLAG_ignition && TopLevelFunctionPassesFilter(FLAG_ignition_filter)) { |
1241 ScriptPassesFilter(FLAG_ignition_script_filter, script)) { | |
1242 if (!GenerateBytecode(info)) { | 1249 if (!GenerateBytecode(info)) { |
1243 return Handle<SharedFunctionInfo>::null(); | 1250 return Handle<SharedFunctionInfo>::null(); |
1244 } | 1251 } |
1245 } else { | 1252 } else { |
1246 if (!CompileUnoptimizedCode(info)) { | 1253 if (!CompileUnoptimizedCode(info)) { |
1247 return Handle<SharedFunctionInfo>::null(); | 1254 return Handle<SharedFunctionInfo>::null(); |
1248 } | 1255 } |
1249 } | 1256 } |
1250 | 1257 |
1251 // Allocate function. | 1258 // Allocate function. |
(...skipping 542 matching lines...) Loading... | |
1794 } | 1801 } |
1795 | 1802 |
1796 #if DEBUG | 1803 #if DEBUG |
1797 void CompilationInfo::PrintAstForTesting() { | 1804 void CompilationInfo::PrintAstForTesting() { |
1798 PrintF("--- Source from AST ---\n%s\n", | 1805 PrintF("--- Source from AST ---\n%s\n", |
1799 PrettyPrinter(isolate()).PrintProgram(literal())); | 1806 PrettyPrinter(isolate()).PrintProgram(literal())); |
1800 } | 1807 } |
1801 #endif | 1808 #endif |
1802 } // namespace internal | 1809 } // namespace internal |
1803 } // namespace v8 | 1810 } // namespace v8 |
OLD | NEW |