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/ast-numbering.h" | 9 #include "src/ast/ast-numbering.h" |
10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 DisableFutureOptimization(); | 94 DisableFutureOptimization(); |
95 dependencies()->Rollback(); | 95 dependencies()->Rollback(); |
96 delete parse_info_; | 96 delete parse_info_; |
97 parse_info_ = nullptr; | 97 parse_info_ = nullptr; |
98 } | 98 } |
99 | 99 |
100 private: | 100 private: |
101 Zone zone_; | 101 Zone zone_; |
102 }; | 102 }; |
103 | 103 |
| 104 // ---------------------------------------------------------------------------- |
| 105 // Implementation of CompilationInfo |
104 | 106 |
105 bool CompilationInfo::has_shared_info() const { | 107 bool CompilationInfo::has_shared_info() const { |
106 return parse_info_ && !parse_info_->shared_info().is_null(); | 108 return parse_info_ && !parse_info_->shared_info().is_null(); |
107 } | 109 } |
108 | 110 |
109 | 111 |
110 bool CompilationInfo::has_context() const { | 112 bool CompilationInfo::has_context() const { |
111 return parse_info_ && !parse_info_->context().is_null(); | 113 return parse_info_ && !parse_info_->context().is_null(); |
112 } | 114 } |
113 | 115 |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 default: | 324 default: |
323 UNIMPLEMENTED(); | 325 UNIMPLEMENTED(); |
324 return StackFrame::NONE; | 326 return StackFrame::NONE; |
325 } | 327 } |
326 } | 328 } |
327 | 329 |
328 bool CompilationInfo::ExpectsJSReceiverAsReceiver() { | 330 bool CompilationInfo::ExpectsJSReceiverAsReceiver() { |
329 return is_sloppy(language_mode()) && !is_native(); | 331 return is_sloppy(language_mode()) && !is_native(); |
330 } | 332 } |
331 | 333 |
| 334 #if DEBUG |
| 335 void CompilationInfo::PrintAstForTesting() { |
| 336 PrintF("--- Source from AST ---\n%s\n", |
| 337 PrettyPrinter(isolate()).PrintProgram(literal())); |
| 338 } |
| 339 #endif |
| 340 |
| 341 // ---------------------------------------------------------------------------- |
| 342 // Implementation of OptimizedCompileJob |
332 | 343 |
333 class HOptimizedGraphBuilderWithPositions: public HOptimizedGraphBuilder { | 344 class HOptimizedGraphBuilderWithPositions: public HOptimizedGraphBuilder { |
334 public: | 345 public: |
335 explicit HOptimizedGraphBuilderWithPositions(CompilationInfo* info) | 346 explicit HOptimizedGraphBuilderWithPositions(CompilationInfo* info) |
336 : HOptimizedGraphBuilder(info) { | 347 : HOptimizedGraphBuilder(info) { |
337 } | 348 } |
338 | 349 |
339 #define DEF_VISIT(type) \ | 350 #define DEF_VISIT(type) \ |
340 void Visit##type(type* node) override { \ | 351 void Visit##type(type* node) override { \ |
341 SourcePosition old_position = SourcePosition::Unknown(); \ | 352 SourcePosition old_position = SourcePosition::Unknown(); \ |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 code_size, | 717 code_size, |
707 compilation_time); | 718 compilation_time); |
708 } | 719 } |
709 if (FLAG_hydrogen_stats) { | 720 if (FLAG_hydrogen_stats) { |
710 isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_create_graph_, | 721 isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_create_graph_, |
711 time_taken_to_optimize_, | 722 time_taken_to_optimize_, |
712 time_taken_to_codegen_); | 723 time_taken_to_codegen_); |
713 } | 724 } |
714 } | 725 } |
715 | 726 |
| 727 // ---------------------------------------------------------------------------- |
| 728 // Local helper methods that make up the compilation pipeline. |
| 729 |
| 730 namespace { |
716 | 731 |
717 // Sets the expected number of properties based on estimate from compiler. | 732 // Sets the expected number of properties based on estimate from compiler. |
718 void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared, | 733 void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared, |
719 int estimate) { | 734 int estimate) { |
720 // If no properties are added in the constructor, they are more likely | 735 // If no properties are added in the constructor, they are more likely |
721 // to be added later. | 736 // to be added later. |
722 if (estimate == 0) estimate = 2; | 737 if (estimate == 0) estimate = 2; |
723 | 738 |
724 // TODO(yangguo): check whether those heuristics are still up-to-date. | 739 // TODO(yangguo): check whether those heuristics are still up-to-date. |
725 // We do not shrink objects that go into a snapshot (yet), so we adjust | 740 // We do not shrink objects that go into a snapshot (yet), so we adjust |
726 // the estimate conservatively. | 741 // the estimate conservatively. |
727 if (shared->GetIsolate()->serializer_enabled()) { | 742 if (shared->GetIsolate()->serializer_enabled()) { |
728 estimate += 2; | 743 estimate += 2; |
729 } else { | 744 } else { |
730 // Inobject slack tracking will reclaim redundant inobject space later, | 745 // Inobject slack tracking will reclaim redundant inobject space later, |
731 // so we can afford to adjust the estimate generously. | 746 // so we can afford to adjust the estimate generously. |
732 estimate += 8; | 747 estimate += 8; |
733 } | 748 } |
734 | 749 |
735 shared->set_expected_nof_properties(estimate); | 750 shared->set_expected_nof_properties(estimate); |
736 } | 751 } |
737 | 752 |
738 | 753 void MaybeDisableOptimization(Handle<SharedFunctionInfo> shared_info, |
739 static void MaybeDisableOptimization(Handle<SharedFunctionInfo> shared_info, | 754 BailoutReason bailout_reason) { |
740 BailoutReason bailout_reason) { | |
741 if (bailout_reason != kNoReason) { | 755 if (bailout_reason != kNoReason) { |
742 shared_info->DisableOptimization(bailout_reason); | 756 shared_info->DisableOptimization(bailout_reason); |
743 } | 757 } |
744 } | 758 } |
745 | 759 |
746 | 760 void RecordFunctionCompilation(Logger::LogEventsAndTags tag, |
747 static void RecordFunctionCompilation(Logger::LogEventsAndTags tag, | 761 CompilationInfo* info, |
748 CompilationInfo* info, | 762 Handle<SharedFunctionInfo> shared) { |
749 Handle<SharedFunctionInfo> shared) { | |
750 // SharedFunctionInfo is passed separately, because if CompilationInfo | 763 // SharedFunctionInfo is passed separately, because if CompilationInfo |
751 // was created using Script object, it will not have it. | 764 // was created using Script object, it will not have it. |
752 | 765 |
753 // Log the code generation. If source information is available include | 766 // Log the code generation. If source information is available include |
754 // script name and line number. Check explicitly whether logging is | 767 // script name and line number. Check explicitly whether logging is |
755 // enabled as finding the line number is not free. | 768 // enabled as finding the line number is not free. |
756 if (info->isolate()->logger()->is_logging_code_events() || | 769 if (info->isolate()->logger()->is_logging_code_events() || |
757 info->isolate()->cpu_profiler()->is_profiling()) { | 770 info->isolate()->cpu_profiler()->is_profiling()) { |
758 Handle<Script> script = info->parse_info()->script(); | 771 Handle<Script> script = info->parse_info()->script(); |
759 Handle<AbstractCode> abstract_code = info->abstract_code(); | 772 Handle<AbstractCode> abstract_code = info->abstract_code(); |
760 if (abstract_code.is_identical_to( | 773 if (abstract_code.is_identical_to( |
761 info->isolate()->builtins()->CompileLazy())) { | 774 info->isolate()->builtins()->CompileLazy())) { |
762 return; | 775 return; |
763 } | 776 } |
764 int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; | 777 int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; |
765 int column_num = | 778 int column_num = |
766 Script::GetColumnNumber(script, shared->start_position()) + 1; | 779 Script::GetColumnNumber(script, shared->start_position()) + 1; |
767 String* script_name = script->name()->IsString() | 780 String* script_name = script->name()->IsString() |
768 ? String::cast(script->name()) | 781 ? String::cast(script->name()) |
769 : info->isolate()->heap()->empty_string(); | 782 : info->isolate()->heap()->empty_string(); |
770 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script); | 783 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script); |
771 PROFILE(info->isolate(), | 784 PROFILE(info->isolate(), |
772 CodeCreateEvent(log_tag, *abstract_code, *shared, info, script_name, | 785 CodeCreateEvent(log_tag, *abstract_code, *shared, info, script_name, |
773 line_num, column_num)); | 786 line_num, column_num)); |
774 } | 787 } |
775 } | 788 } |
776 | 789 |
777 static bool CompileUnoptimizedCode(CompilationInfo* info) { | 790 bool CompileUnoptimizedCode(CompilationInfo* info) { |
778 DCHECK(AllowCompilation::IsAllowed(info->isolate())); | 791 DCHECK(AllowCompilation::IsAllowed(info->isolate())); |
779 if (!Compiler::Analyze(info->parse_info()) || | 792 if (!Compiler::Analyze(info->parse_info()) || |
780 !FullCodeGenerator::MakeCode(info)) { | 793 !FullCodeGenerator::MakeCode(info)) { |
781 Isolate* isolate = info->isolate(); | 794 Isolate* isolate = info->isolate(); |
782 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 795 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
783 return false; | 796 return false; |
784 } | 797 } |
785 return true; | 798 return true; |
786 } | 799 } |
787 | 800 |
788 static bool UseIgnition(CompilationInfo* info) { | 801 bool UseIgnition(CompilationInfo* info) { |
789 // TODO(4681): Generator functions are not yet supported. | 802 // TODO(4681): Generator functions are not yet supported. |
790 if ((info->has_shared_info() && info->shared_info()->is_generator()) || | 803 if ((info->has_shared_info() && info->shared_info()->is_generator()) || |
791 (info->has_literal() && IsGeneratorFunction(info->literal()->kind()))) { | 804 (info->has_literal() && IsGeneratorFunction(info->literal()->kind()))) { |
792 return false; | 805 return false; |
793 } | 806 } |
794 | 807 |
795 // TODO(4681): Resuming a suspended frame is not supported. | 808 // TODO(4681): Resuming a suspended frame is not supported. |
796 if (info->has_shared_info() && info->shared_info()->HasBuiltinFunctionId() && | 809 if (info->has_shared_info() && info->shared_info()->HasBuiltinFunctionId() && |
797 (info->shared_info()->builtin_function_id() == kGeneratorObjectNext || | 810 (info->shared_info()->builtin_function_id() == kGeneratorObjectNext || |
798 info->shared_info()->builtin_function_id() == kGeneratorObjectReturn || | 811 info->shared_info()->builtin_function_id() == kGeneratorObjectReturn || |
799 info->shared_info()->builtin_function_id() == kGeneratorObjectThrow)) { | 812 info->shared_info()->builtin_function_id() == kGeneratorObjectThrow)) { |
800 return false; | 813 return false; |
801 } | 814 } |
802 | 815 |
803 // Checks whether top level functions should be passed by the filter. | 816 // Checks whether top level functions should be passed by the filter. |
804 if (info->closure().is_null()) { | 817 if (info->closure().is_null()) { |
805 Vector<const char> filter = CStrVector(FLAG_ignition_filter); | 818 Vector<const char> filter = CStrVector(FLAG_ignition_filter); |
806 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); | 819 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); |
807 } | 820 } |
808 | 821 |
809 // Finally respect the filter. | 822 // Finally respect the filter. |
810 return info->closure()->PassesFilter(FLAG_ignition_filter); | 823 return info->closure()->PassesFilter(FLAG_ignition_filter); |
811 } | 824 } |
812 | 825 |
813 static int CodeAndMetadataSize(CompilationInfo* info) { | 826 int CodeAndMetadataSize(CompilationInfo* info) { |
814 int size = 0; | 827 int size = 0; |
815 if (info->has_bytecode_array()) { | 828 if (info->has_bytecode_array()) { |
816 Handle<BytecodeArray> bytecode_array = info->bytecode_array(); | 829 Handle<BytecodeArray> bytecode_array = info->bytecode_array(); |
817 size += bytecode_array->BytecodeArraySize(); | 830 size += bytecode_array->BytecodeArraySize(); |
818 size += bytecode_array->constant_pool()->Size(); | 831 size += bytecode_array->constant_pool()->Size(); |
819 size += bytecode_array->handler_table()->Size(); | 832 size += bytecode_array->handler_table()->Size(); |
820 size += bytecode_array->source_position_table()->Size(); | 833 size += bytecode_array->source_position_table()->Size(); |
821 } else { | 834 } else { |
822 Handle<Code> code = info->code(); | 835 Handle<Code> code = info->code(); |
823 size += code->CodeSize(); | 836 size += code->CodeSize(); |
824 size += code->relocation_info()->Size(); | 837 size += code->relocation_info()->Size(); |
825 size += code->deoptimization_data()->Size(); | 838 size += code->deoptimization_data()->Size(); |
826 size += code->handler_table()->Size(); | 839 size += code->handler_table()->Size(); |
827 } | 840 } |
828 return size; | 841 return size; |
829 } | 842 } |
830 | 843 |
831 | 844 bool GenerateBaselineCode(CompilationInfo* info) { |
832 static bool GenerateBaselineCode(CompilationInfo* info) { | |
833 bool success; | 845 bool success; |
834 if (FLAG_ignition && UseIgnition(info)) { | 846 if (FLAG_ignition && UseIgnition(info)) { |
835 success = interpreter::Interpreter::MakeBytecode(info); | 847 success = interpreter::Interpreter::MakeBytecode(info); |
836 } else { | 848 } else { |
837 success = FullCodeGenerator::MakeCode(info); | 849 success = FullCodeGenerator::MakeCode(info); |
838 } | 850 } |
839 if (success) { | 851 if (success) { |
840 Isolate* isolate = info->isolate(); | 852 Isolate* isolate = info->isolate(); |
841 Counters* counters = isolate->counters(); | 853 Counters* counters = isolate->counters(); |
842 counters->total_baseline_code_size()->Increment(CodeAndMetadataSize(info)); | 854 counters->total_baseline_code_size()->Increment(CodeAndMetadataSize(info)); |
843 counters->total_baseline_compile_count()->Increment(1); | 855 counters->total_baseline_compile_count()->Increment(1); |
844 } | 856 } |
845 return success; | 857 return success; |
846 } | 858 } |
847 | 859 |
848 | 860 bool CompileBaselineCode(CompilationInfo* info) { |
849 static bool CompileBaselineCode(CompilationInfo* info) { | |
850 DCHECK(AllowCompilation::IsAllowed(info->isolate())); | 861 DCHECK(AllowCompilation::IsAllowed(info->isolate())); |
851 if (!Compiler::Analyze(info->parse_info()) || !GenerateBaselineCode(info)) { | 862 if (!Compiler::Analyze(info->parse_info()) || !GenerateBaselineCode(info)) { |
852 Isolate* isolate = info->isolate(); | 863 Isolate* isolate = info->isolate(); |
853 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 864 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
854 return false; | 865 return false; |
855 } | 866 } |
856 return true; | 867 return true; |
857 } | 868 } |
858 | 869 |
859 static void InstallBaselineCompilationResult(CompilationInfo* info, | 870 void InstallBaselineCompilationResult(CompilationInfo* info, |
860 Handle<SharedFunctionInfo> shared, | 871 Handle<SharedFunctionInfo> shared, |
861 Handle<ScopeInfo> scope_info) { | 872 Handle<ScopeInfo> scope_info) { |
862 // Assert that we are not overwriting (possibly patched) debug code. | 873 // Assert that we are not overwriting (possibly patched) debug code. |
863 DCHECK(!shared->HasDebugCode()); | 874 DCHECK(!shared->HasDebugCode()); |
864 DCHECK(!info->code().is_null()); | 875 DCHECK(!info->code().is_null()); |
865 shared->ReplaceCode(*info->code()); | 876 shared->ReplaceCode(*info->code()); |
866 shared->set_scope_info(*scope_info); | 877 shared->set_scope_info(*scope_info); |
867 shared->set_feedback_vector(*info->feedback_vector()); | 878 shared->set_feedback_vector(*info->feedback_vector()); |
868 if (info->has_bytecode_array()) { | 879 if (info->has_bytecode_array()) { |
869 DCHECK(!shared->HasBytecodeArray()); // Only compiled once. | 880 DCHECK(!shared->HasBytecodeArray()); // Only compiled once. |
870 shared->set_bytecode_array(*info->bytecode_array()); | 881 shared->set_bytecode_array(*info->bytecode_array()); |
871 } | 882 } |
872 } | 883 } |
873 | 884 |
874 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( | 885 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCodeCommon( |
875 CompilationInfo* info) { | 886 CompilationInfo* info) { |
876 VMState<COMPILER> state(info->isolate()); | 887 VMState<COMPILER> state(info->isolate()); |
877 PostponeInterruptsScope postpone(info->isolate()); | 888 PostponeInterruptsScope postpone(info->isolate()); |
878 | 889 |
879 // Parse and update CompilationInfo with the results. | 890 // Parse and update CompilationInfo with the results. |
880 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); | 891 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); |
881 Handle<SharedFunctionInfo> shared = info->shared_info(); | 892 Handle<SharedFunctionInfo> shared = info->shared_info(); |
882 FunctionLiteral* lit = info->literal(); | 893 FunctionLiteral* lit = info->literal(); |
883 DCHECK_EQ(shared->language_mode(), lit->language_mode()); | 894 DCHECK_EQ(shared->language_mode(), lit->language_mode()); |
884 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); | 895 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); |
885 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); | 896 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); |
886 | 897 |
887 // Compile either unoptimized code or bytecode for the interpreter. | 898 // Compile either unoptimized code or bytecode for the interpreter. |
888 if (!CompileBaselineCode(info)) return MaybeHandle<Code>(); | 899 if (!CompileBaselineCode(info)) return MaybeHandle<Code>(); |
889 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); | 900 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); |
890 | 901 |
891 // Update the shared function info with the scope info. Allocating the | 902 // Update the shared function info with the scope info. Allocating the |
892 // ScopeInfo object may cause a GC. | 903 // ScopeInfo object may cause a GC. |
893 Handle<ScopeInfo> scope_info = | 904 Handle<ScopeInfo> scope_info = |
894 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); | 905 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); |
895 | 906 |
896 // Install compilation result on the shared function info | 907 // Install compilation result on the shared function info |
897 InstallBaselineCompilationResult(info, shared, scope_info); | 908 InstallBaselineCompilationResult(info, shared, scope_info); |
898 | 909 |
899 return info->code(); | 910 return info->code(); |
900 } | 911 } |
901 | 912 |
902 | 913 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( |
903 MUST_USE_RESULT static MaybeHandle<Code> GetCodeFromOptimizedCodeMap( | |
904 Handle<JSFunction> function, BailoutId osr_ast_id) { | 914 Handle<JSFunction> function, BailoutId osr_ast_id) { |
905 Handle<SharedFunctionInfo> shared(function->shared()); | 915 Handle<SharedFunctionInfo> shared(function->shared()); |
906 DisallowHeapAllocation no_gc; | 916 DisallowHeapAllocation no_gc; |
907 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( | 917 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( |
908 function->context()->native_context(), osr_ast_id); | 918 function->context()->native_context(), osr_ast_id); |
909 if (cached.code != nullptr) { | 919 if (cached.code != nullptr) { |
910 // Caching of optimized code enabled and optimized code found. | 920 // Caching of optimized code enabled and optimized code found. |
911 if (cached.literals != nullptr) function->set_literals(cached.literals); | 921 if (cached.literals != nullptr) function->set_literals(cached.literals); |
912 DCHECK(!cached.code->marked_for_deoptimization()); | 922 DCHECK(!cached.code->marked_for_deoptimization()); |
913 DCHECK(function->shared()->is_compiled()); | 923 DCHECK(function->shared()->is_compiled()); |
914 return Handle<Code>(cached.code); | 924 return Handle<Code>(cached.code); |
915 } | 925 } |
916 return MaybeHandle<Code>(); | 926 return MaybeHandle<Code>(); |
917 } | 927 } |
918 | 928 |
919 | 929 void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { |
920 static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { | |
921 Handle<Code> code = info->code(); | 930 Handle<Code> code = info->code(); |
922 if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do. | 931 if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do. |
923 | 932 |
924 // Function context specialization folds-in the function context, | 933 // Function context specialization folds-in the function context, |
925 // so no sharing can occur. | 934 // so no sharing can occur. |
926 if (info->is_function_context_specializing()) return; | 935 if (info->is_function_context_specializing()) return; |
927 // Frame specialization implies function context specialization. | 936 // Frame specialization implies function context specialization. |
928 DCHECK(!info->is_frame_specializing()); | 937 DCHECK(!info->is_frame_specializing()); |
929 | 938 |
930 // Cache optimized context-specific code. | 939 // Cache optimized context-specific code. |
(...skipping 10 matching lines...) Expand all Loading... |
941 // Cache optimized (native) context-independent code. | 950 // Cache optimized (native) context-independent code. |
942 if (FLAG_turbo_cache_shared_code && code->is_turbofanned() && | 951 if (FLAG_turbo_cache_shared_code && code->is_turbofanned() && |
943 !info->is_native_context_specializing()) { | 952 !info->is_native_context_specializing()) { |
944 DCHECK(!info->is_function_context_specializing()); | 953 DCHECK(!info->is_function_context_specializing()); |
945 DCHECK(info->osr_ast_id().IsNone()); | 954 DCHECK(info->osr_ast_id().IsNone()); |
946 Handle<SharedFunctionInfo> shared(function->shared()); | 955 Handle<SharedFunctionInfo> shared(function->shared()); |
947 SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap(shared, code); | 956 SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap(shared, code); |
948 } | 957 } |
949 } | 958 } |
950 | 959 |
951 | 960 bool Renumber(ParseInfo* parse_info) { |
952 static bool Renumber(ParseInfo* parse_info) { | |
953 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), | 961 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), |
954 parse_info->literal())) { | 962 parse_info->literal())) { |
955 return false; | 963 return false; |
956 } | 964 } |
957 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); | 965 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); |
958 if (!shared_info.is_null()) { | 966 if (!shared_info.is_null()) { |
959 FunctionLiteral* lit = parse_info->literal(); | 967 FunctionLiteral* lit = parse_info->literal(); |
960 shared_info->set_ast_node_count(lit->ast_node_count()); | 968 shared_info->set_ast_node_count(lit->ast_node_count()); |
961 MaybeDisableOptimization(shared_info, lit->dont_optimize_reason()); | 969 MaybeDisableOptimization(shared_info, lit->dont_optimize_reason()); |
962 shared_info->set_dont_crankshaft( | 970 shared_info->set_dont_crankshaft( |
963 shared_info->dont_crankshaft() || | 971 shared_info->dont_crankshaft() || |
964 (lit->flags() & AstProperties::kDontCrankshaft)); | 972 (lit->flags() & AstProperties::kDontCrankshaft)); |
965 } | 973 } |
966 return true; | 974 return true; |
967 } | 975 } |
968 | 976 |
969 | |
970 bool Compiler::Analyze(ParseInfo* info) { | |
971 DCHECK_NOT_NULL(info->literal()); | |
972 if (!Rewriter::Rewrite(info)) return false; | |
973 if (!Scope::Analyze(info)) return false; | |
974 if (!Renumber(info)) return false; | |
975 DCHECK_NOT_NULL(info->scope()); | |
976 return true; | |
977 } | |
978 | |
979 | |
980 bool Compiler::ParseAndAnalyze(ParseInfo* info) { | |
981 if (!Parser::ParseStatic(info)) return false; | |
982 return Compiler::Analyze(info); | |
983 } | |
984 | |
985 namespace { | |
986 | |
987 bool GetOptimizedCodeNow(CompilationInfo* info) { | 977 bool GetOptimizedCodeNow(CompilationInfo* info) { |
988 Isolate* isolate = info->isolate(); | 978 Isolate* isolate = info->isolate(); |
989 CanonicalHandleScope canonical(isolate); | 979 CanonicalHandleScope canonical(isolate); |
990 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); | 980 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); |
991 TRACE_EVENT0("v8", "V8.OptimizeCode"); | 981 TRACE_EVENT0("v8", "V8.OptimizeCode"); |
992 | 982 |
993 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; | 983 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
994 | 984 |
995 TimerEventScope<TimerEventRecompileSynchronous> timer(isolate); | 985 TimerEventScope<TimerEventRecompileSynchronous> timer(isolate); |
996 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); | 986 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1175 Handle<Code> opt_code; | 1165 Handle<Code> opt_code; |
1176 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) | 1166 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) |
1177 .ToHandle(&opt_code)) { | 1167 .ToHandle(&opt_code)) { |
1178 result = opt_code; | 1168 result = opt_code; |
1179 } | 1169 } |
1180 } | 1170 } |
1181 | 1171 |
1182 return result; | 1172 return result; |
1183 } | 1173 } |
1184 | 1174 |
1185 } // namespace | |
1186 | |
1187 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { | |
1188 if (function->is_compiled()) return true; | |
1189 MaybeHandle<Code> maybe_code = GetLazyCode(function); | |
1190 Handle<Code> code; | |
1191 if (!maybe_code.ToHandle(&code)) { | |
1192 if (flag == CLEAR_EXCEPTION) { | |
1193 function->GetIsolate()->clear_pending_exception(); | |
1194 } | |
1195 return false; | |
1196 } | |
1197 DCHECK(code->IsJavaScriptCode()); | |
1198 function->ReplaceCode(*code); | |
1199 DCHECK(function->is_compiled()); | |
1200 return true; | |
1201 } | |
1202 | |
1203 bool Compiler::CompileOptimized(Handle<JSFunction> function, | |
1204 ConcurrencyMode mode) { | |
1205 Handle<Code> code; | |
1206 if (GetOptimizedCode(function, mode).ToHandle(&code)) { | |
1207 // Optimization succeeded, return optimized code. | |
1208 function->ReplaceCode(*code); | |
1209 } else { | |
1210 // Optimization failed, get unoptimized code. | |
1211 Isolate* isolate = function->GetIsolate(); | |
1212 if (isolate->has_pending_exception()) { // Possible stack overflow. | |
1213 return false; | |
1214 } | |
1215 code = Handle<Code>(function->shared()->code(), isolate); | |
1216 if (code->kind() != Code::FUNCTION && | |
1217 code->kind() != Code::OPTIMIZED_FUNCTION) { | |
1218 if (!GetUnoptimizedCode(function).ToHandle(&code)) { | |
1219 return false; | |
1220 } | |
1221 } | |
1222 function->ReplaceCode(*code); | |
1223 } | |
1224 | |
1225 DCHECK(function->code()->kind() == Code::FUNCTION || | |
1226 function->code()->kind() == Code::OPTIMIZED_FUNCTION || | |
1227 (function->code()->is_interpreter_entry_trampoline() && | |
1228 function->shared()->HasBytecodeArray()) || | |
1229 function->IsInOptimizationQueue()); | |
1230 return true; | |
1231 } | |
1232 | |
1233 // TODO(turbofan): In the future, unoptimized code with deopt support could | |
1234 // be generated lazily once deopt is triggered. | |
1235 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | |
1236 DCHECK_NOT_NULL(info->literal()); | |
1237 DCHECK(info->has_scope()); | |
1238 Handle<SharedFunctionInfo> shared = info->shared_info(); | |
1239 if (!shared->has_deoptimization_support()) { | |
1240 // TODO(titzer): just reuse the ParseInfo for the unoptimized compile. | |
1241 CompilationInfoWithZone unoptimized(info->closure()); | |
1242 // Note that we use the same AST that we will use for generating the | |
1243 // optimized code. | |
1244 ParseInfo* parse_info = unoptimized.parse_info(); | |
1245 parse_info->set_literal(info->literal()); | |
1246 parse_info->set_scope(info->scope()); | |
1247 parse_info->set_context(info->context()); | |
1248 unoptimized.EnableDeoptimizationSupport(); | |
1249 // If the current code has reloc info for serialization, also include | |
1250 // reloc info for serialization for the new code, so that deopt support | |
1251 // can be added without losing IC state. | |
1252 if (shared->code()->kind() == Code::FUNCTION && | |
1253 shared->code()->has_reloc_info_for_serialization()) { | |
1254 unoptimized.PrepareForSerializing(); | |
1255 } | |
1256 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; | |
1257 | |
1258 shared->EnableDeoptimizationSupport(*unoptimized.code()); | |
1259 shared->set_feedback_vector(*unoptimized.feedback_vector()); | |
1260 | |
1261 info->MarkAsCompiled(); | |
1262 | |
1263 // The scope info might not have been set if a lazily compiled | |
1264 // function is inlined before being called for the first time. | |
1265 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { | |
1266 Handle<ScopeInfo> target_scope_info = | |
1267 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); | |
1268 shared->set_scope_info(*target_scope_info); | |
1269 } | |
1270 | |
1271 // The existing unoptimized code was replaced with the new one. | |
1272 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized, shared); | |
1273 } | |
1274 return true; | |
1275 } | |
1276 | |
1277 | 1175 |
1278 bool CompileEvalForDebugging(Handle<JSFunction> function, | 1176 bool CompileEvalForDebugging(Handle<JSFunction> function, |
1279 Handle<SharedFunctionInfo> shared) { | 1177 Handle<SharedFunctionInfo> shared) { |
1280 Handle<Script> script(Script::cast(shared->script())); | 1178 Handle<Script> script(Script::cast(shared->script())); |
1281 Handle<Context> context(function->context()); | 1179 Handle<Context> context(function->context()); |
1282 | 1180 |
1283 Zone zone; | 1181 Zone zone; |
1284 ParseInfo parse_info(&zone, script); | 1182 ParseInfo parse_info(&zone, script); |
1285 CompilationInfo info(&parse_info); | 1183 CompilationInfo info(&parse_info); |
1286 Isolate* isolate = info.isolate(); | 1184 Isolate* isolate = info.isolate(); |
(...skipping 28 matching lines...) Expand all Loading... |
1315 | 1213 |
1316 bool CompileForDebugging(CompilationInfo* info) { | 1214 bool CompileForDebugging(CompilationInfo* info) { |
1317 info->MarkAsDebug(); | 1215 info->MarkAsDebug(); |
1318 if (GetUnoptimizedCodeCommon(info).is_null()) { | 1216 if (GetUnoptimizedCodeCommon(info).is_null()) { |
1319 info->isolate()->clear_pending_exception(); | 1217 info->isolate()->clear_pending_exception(); |
1320 return false; | 1218 return false; |
1321 } | 1219 } |
1322 return true; | 1220 return true; |
1323 } | 1221 } |
1324 | 1222 |
1325 | 1223 inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { |
1326 static inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { | |
1327 return shared->is_toplevel() && shared->script()->IsScript() && | 1224 return shared->is_toplevel() && shared->script()->IsScript() && |
1328 Script::cast(shared->script())->compilation_type() == | 1225 Script::cast(shared->script())->compilation_type() == |
1329 Script::COMPILATION_TYPE_EVAL; | 1226 Script::COMPILATION_TYPE_EVAL; |
1330 } | 1227 } |
1331 | 1228 |
1332 | 1229 Handle<SharedFunctionInfo> NewSharedFunctionInfoForLiteral( |
1333 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { | |
1334 Handle<SharedFunctionInfo> shared(function->shared()); | |
1335 if (IsEvalToplevel(shared)) { | |
1336 return CompileEvalForDebugging(function, shared); | |
1337 } else { | |
1338 CompilationInfoWithZone info(function); | |
1339 return CompileForDebugging(&info); | |
1340 } | |
1341 } | |
1342 | |
1343 | |
1344 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { | |
1345 DCHECK(shared->allows_lazy_compilation_without_context()); | |
1346 DCHECK(!IsEvalToplevel(shared)); | |
1347 Zone zone; | |
1348 ParseInfo parse_info(&zone, shared); | |
1349 CompilationInfo info(&parse_info); | |
1350 return CompileForDebugging(&info); | |
1351 } | |
1352 | |
1353 | |
1354 void Compiler::CompileForLiveEdit(Handle<Script> script) { | |
1355 // TODO(635): support extensions. | |
1356 Zone zone; | |
1357 ParseInfo parse_info(&zone, script); | |
1358 CompilationInfo info(&parse_info); | |
1359 PostponeInterruptsScope postpone(info.isolate()); | |
1360 VMState<COMPILER> state(info.isolate()); | |
1361 | |
1362 // Get rid of old list of shared function infos. | |
1363 info.MarkAsFirstCompile(); | |
1364 info.MarkAsDebug(); | |
1365 info.parse_info()->set_global(); | |
1366 if (!Parser::ParseStatic(info.parse_info())) return; | |
1367 | |
1368 LiveEditFunctionTracker tracker(info.isolate(), parse_info.literal()); | |
1369 if (!CompileUnoptimizedCode(&info)) return; | |
1370 if (info.has_shared_info()) { | |
1371 Handle<ScopeInfo> scope_info = | |
1372 ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); | |
1373 info.shared_info()->set_scope_info(*scope_info); | |
1374 } | |
1375 tracker.RecordRootFunctionInfo(info.code()); | |
1376 } | |
1377 | |
1378 static Handle<SharedFunctionInfo> NewSharedFunctionInfoForLiteral( | |
1379 Isolate* isolate, FunctionLiteral* literal, Handle<Script> script) { | 1230 Isolate* isolate, FunctionLiteral* literal, Handle<Script> script) { |
1380 Handle<Code> code = isolate->builtins()->CompileLazy(); | 1231 Handle<Code> code = isolate->builtins()->CompileLazy(); |
1381 Handle<ScopeInfo> scope_info = handle(ScopeInfo::Empty(isolate)); | 1232 Handle<ScopeInfo> scope_info = handle(ScopeInfo::Empty(isolate)); |
1382 Handle<SharedFunctionInfo> result = isolate->factory()->NewSharedFunctionInfo( | 1233 Handle<SharedFunctionInfo> result = isolate->factory()->NewSharedFunctionInfo( |
1383 literal->name(), literal->materialized_literal_count(), literal->kind(), | 1234 literal->name(), literal->materialized_literal_count(), literal->kind(), |
1384 code, scope_info); | 1235 code, scope_info); |
1385 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); | 1236 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); |
1386 SharedFunctionInfo::SetScript(result, script); | 1237 SharedFunctionInfo::SetScript(result, script); |
1387 return result; | 1238 return result; |
1388 } | 1239 } |
1389 | 1240 |
1390 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { | 1241 Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { |
1391 Isolate* isolate = info->isolate(); | 1242 Isolate* isolate = info->isolate(); |
1392 TimerEventScope<TimerEventCompileCode> timer(isolate); | 1243 TimerEventScope<TimerEventCompileCode> timer(isolate); |
1393 TRACE_EVENT0("v8", "V8.CompileCode"); | 1244 TRACE_EVENT0("v8", "V8.CompileCode"); |
1394 PostponeInterruptsScope postpone(isolate); | 1245 PostponeInterruptsScope postpone(isolate); |
1395 DCHECK(!isolate->native_context().is_null()); | 1246 DCHECK(!isolate->native_context().is_null()); |
1396 ParseInfo* parse_info = info->parse_info(); | 1247 ParseInfo* parse_info = info->parse_info(); |
1397 Handle<Script> script = parse_info->script(); | 1248 Handle<Script> script = parse_info->script(); |
1398 | 1249 |
1399 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? | 1250 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? |
1400 FixedArray* array = isolate->native_context()->embedder_data(); | 1251 FixedArray* array = isolate->native_context()->embedder_data(); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1493 | 1344 |
1494 if (!script.is_null()) | 1345 if (!script.is_null()) |
1495 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED); | 1346 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED); |
1496 | 1347 |
1497 live_edit_tracker.RecordFunctionInfo(result, lit, info->zone()); | 1348 live_edit_tracker.RecordFunctionInfo(result, lit, info->zone()); |
1498 } | 1349 } |
1499 | 1350 |
1500 return result; | 1351 return result; |
1501 } | 1352 } |
1502 | 1353 |
| 1354 } // namespace |
| 1355 |
| 1356 // ---------------------------------------------------------------------------- |
| 1357 // Implementation of Compiler |
| 1358 |
| 1359 bool Compiler::Analyze(ParseInfo* info) { |
| 1360 DCHECK_NOT_NULL(info->literal()); |
| 1361 if (!Rewriter::Rewrite(info)) return false; |
| 1362 if (!Scope::Analyze(info)) return false; |
| 1363 if (!Renumber(info)) return false; |
| 1364 DCHECK_NOT_NULL(info->scope()); |
| 1365 return true; |
| 1366 } |
| 1367 |
| 1368 bool Compiler::ParseAndAnalyze(ParseInfo* info) { |
| 1369 if (!Parser::ParseStatic(info)) return false; |
| 1370 return Compiler::Analyze(info); |
| 1371 } |
| 1372 |
| 1373 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { |
| 1374 if (function->is_compiled()) return true; |
| 1375 MaybeHandle<Code> maybe_code = GetLazyCode(function); |
| 1376 Handle<Code> code; |
| 1377 if (!maybe_code.ToHandle(&code)) { |
| 1378 if (flag == CLEAR_EXCEPTION) { |
| 1379 function->GetIsolate()->clear_pending_exception(); |
| 1380 } |
| 1381 return false; |
| 1382 } |
| 1383 DCHECK(code->IsJavaScriptCode()); |
| 1384 function->ReplaceCode(*code); |
| 1385 DCHECK(function->is_compiled()); |
| 1386 return true; |
| 1387 } |
| 1388 |
| 1389 bool Compiler::CompileOptimized(Handle<JSFunction> function, |
| 1390 ConcurrencyMode mode) { |
| 1391 Handle<Code> code; |
| 1392 if (GetOptimizedCode(function, mode).ToHandle(&code)) { |
| 1393 // Optimization succeeded, return optimized code. |
| 1394 function->ReplaceCode(*code); |
| 1395 } else { |
| 1396 // Optimization failed, get unoptimized code. |
| 1397 Isolate* isolate = function->GetIsolate(); |
| 1398 if (isolate->has_pending_exception()) { // Possible stack overflow. |
| 1399 return false; |
| 1400 } |
| 1401 code = Handle<Code>(function->shared()->code(), isolate); |
| 1402 if (code->kind() != Code::FUNCTION && |
| 1403 code->kind() != Code::OPTIMIZED_FUNCTION) { |
| 1404 if (!GetUnoptimizedCode(function).ToHandle(&code)) { |
| 1405 return false; |
| 1406 } |
| 1407 } |
| 1408 function->ReplaceCode(*code); |
| 1409 } |
| 1410 |
| 1411 DCHECK(function->code()->kind() == Code::FUNCTION || |
| 1412 function->code()->kind() == Code::OPTIMIZED_FUNCTION || |
| 1413 (function->code()->is_interpreter_entry_trampoline() && |
| 1414 function->shared()->HasBytecodeArray()) || |
| 1415 function->IsInOptimizationQueue()); |
| 1416 return true; |
| 1417 } |
| 1418 |
| 1419 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { |
| 1420 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1421 if (IsEvalToplevel(shared)) { |
| 1422 return CompileEvalForDebugging(function, shared); |
| 1423 } else { |
| 1424 CompilationInfoWithZone info(function); |
| 1425 return CompileForDebugging(&info); |
| 1426 } |
| 1427 } |
| 1428 |
| 1429 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { |
| 1430 DCHECK(shared->allows_lazy_compilation_without_context()); |
| 1431 DCHECK(!IsEvalToplevel(shared)); |
| 1432 Zone zone; |
| 1433 ParseInfo parse_info(&zone, shared); |
| 1434 CompilationInfo info(&parse_info); |
| 1435 return CompileForDebugging(&info); |
| 1436 } |
| 1437 |
| 1438 // TODO(turbofan): In the future, unoptimized code with deopt support could |
| 1439 // be generated lazily once deopt is triggered. |
| 1440 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
| 1441 DCHECK_NOT_NULL(info->literal()); |
| 1442 DCHECK(info->has_scope()); |
| 1443 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 1444 if (!shared->has_deoptimization_support()) { |
| 1445 // TODO(titzer): just reuse the ParseInfo for the unoptimized compile. |
| 1446 CompilationInfoWithZone unoptimized(info->closure()); |
| 1447 // Note that we use the same AST that we will use for generating the |
| 1448 // optimized code. |
| 1449 ParseInfo* parse_info = unoptimized.parse_info(); |
| 1450 parse_info->set_literal(info->literal()); |
| 1451 parse_info->set_scope(info->scope()); |
| 1452 parse_info->set_context(info->context()); |
| 1453 unoptimized.EnableDeoptimizationSupport(); |
| 1454 // If the current code has reloc info for serialization, also include |
| 1455 // reloc info for serialization for the new code, so that deopt support |
| 1456 // can be added without losing IC state. |
| 1457 if (shared->code()->kind() == Code::FUNCTION && |
| 1458 shared->code()->has_reloc_info_for_serialization()) { |
| 1459 unoptimized.PrepareForSerializing(); |
| 1460 } |
| 1461 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; |
| 1462 |
| 1463 shared->EnableDeoptimizationSupport(*unoptimized.code()); |
| 1464 shared->set_feedback_vector(*unoptimized.feedback_vector()); |
| 1465 |
| 1466 info->MarkAsCompiled(); |
| 1467 |
| 1468 // The scope info might not have been set if a lazily compiled |
| 1469 // function is inlined before being called for the first time. |
| 1470 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { |
| 1471 Handle<ScopeInfo> target_scope_info = |
| 1472 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); |
| 1473 shared->set_scope_info(*target_scope_info); |
| 1474 } |
| 1475 |
| 1476 // The existing unoptimized code was replaced with the new one. |
| 1477 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized, shared); |
| 1478 } |
| 1479 return true; |
| 1480 } |
| 1481 |
| 1482 void Compiler::CompileForLiveEdit(Handle<Script> script) { |
| 1483 // TODO(635): support extensions. |
| 1484 Zone zone; |
| 1485 ParseInfo parse_info(&zone, script); |
| 1486 CompilationInfo info(&parse_info); |
| 1487 PostponeInterruptsScope postpone(info.isolate()); |
| 1488 VMState<COMPILER> state(info.isolate()); |
| 1489 |
| 1490 // Get rid of old list of shared function infos. |
| 1491 info.MarkAsFirstCompile(); |
| 1492 info.MarkAsDebug(); |
| 1493 info.parse_info()->set_global(); |
| 1494 if (!Parser::ParseStatic(info.parse_info())) return; |
| 1495 |
| 1496 LiveEditFunctionTracker tracker(info.isolate(), parse_info.literal()); |
| 1497 if (!CompileUnoptimizedCode(&info)) return; |
| 1498 if (info.has_shared_info()) { |
| 1499 Handle<ScopeInfo> scope_info = |
| 1500 ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
| 1501 info.shared_info()->set_scope_info(*scope_info); |
| 1502 } |
| 1503 tracker.RecordRootFunctionInfo(info.code()); |
| 1504 } |
1503 | 1505 |
1504 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( | 1506 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( |
1505 Handle<String> source, Handle<SharedFunctionInfo> outer_info, | 1507 Handle<String> source, Handle<SharedFunctionInfo> outer_info, |
1506 Handle<Context> context, LanguageMode language_mode, | 1508 Handle<Context> context, LanguageMode language_mode, |
1507 ParseRestriction restriction, int line_offset, int column_offset, | 1509 ParseRestriction restriction, int line_offset, int column_offset, |
1508 Handle<Object> script_name, ScriptOriginOptions options) { | 1510 Handle<Object> script_name, ScriptOriginOptions options) { |
1509 Isolate* isolate = source->GetIsolate(); | 1511 Isolate* isolate = source->GetIsolate(); |
1510 int source_length = source->length(); | 1512 int source_length = source->length(); |
1511 isolate->counters()->total_eval_size()->Increment(source_length); | 1513 isolate->counters()->total_eval_size()->Increment(source_length); |
1512 isolate->counters()->total_compile_size()->Increment(source_length); | 1514 isolate->counters()->total_compile_size()->Increment(source_length); |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1946 | 1948 |
1947 // Cache context-specific literals. | 1949 // Cache context-specific literals. |
1948 MaybeHandle<Code> code; | 1950 MaybeHandle<Code> code; |
1949 if (cached.code != nullptr) code = handle(cached.code); | 1951 if (cached.code != nullptr) code = handle(cached.code); |
1950 Handle<Context> native_context(function->context()->native_context()); | 1952 Handle<Context> native_context(function->context()->native_context()); |
1951 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | 1953 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, |
1952 literals, BailoutId::None()); | 1954 literals, BailoutId::None()); |
1953 } | 1955 } |
1954 } | 1956 } |
1955 | 1957 |
1956 #if DEBUG | |
1957 void CompilationInfo::PrintAstForTesting() { | |
1958 PrintF("--- Source from AST ---\n%s\n", | |
1959 PrettyPrinter(isolate()).PrintProgram(literal())); | |
1960 } | |
1961 #endif | |
1962 | |
1963 } // namespace internal | 1958 } // namespace internal |
1964 } // namespace v8 | 1959 } // namespace v8 |
OLD | NEW |