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

Side by Side Diff: src/compiler.cc

Issue 10807024: Optimize functions on a second thread. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « src/compiler.h ('k') | src/d8.h » ('j') | src/execution.cc » ('J')
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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 } else { 651 } else {
652 if (result->ic_age() != HEAP->global_ic_age()) { 652 if (result->ic_age() != HEAP->global_ic_age()) {
653 result->ResetForNewContext(HEAP->global_ic_age()); 653 result->ResetForNewContext(HEAP->global_ic_age());
654 } 654 }
655 } 655 }
656 656
657 return result; 657 return result;
658 } 658 }
659 659
660 660
661 bool Compiler::CompileLazy(CompilationInfo* info) { 661 static bool InstallFullCode(CompilationInfo* info) {
662 Isolate* isolate = info->isolate(); 662 // Update the shared function info with the compiled code and the
663 // scope info. Please note, that the order of the shared function
664 // info initialization is important since set_scope_info might
665 // trigger a GC, causing the ASSERT below to be invalid if the code
666 // was flushed. By setting the code object last we avoid this.
667 Handle<SharedFunctionInfo> shared = info->shared_info();
668 Handle<Code> code = info->code();
669 Handle<JSFunction> function = info->closure();
670 Handle<ScopeInfo> scope_info =
671 ScopeInfo::Create(info->scope(), info->zone());
672 shared->set_scope_info(*scope_info);
673 shared->set_code(*code);
674 if (!function.is_null()) {
675 function->ReplaceCode(*code);
676 ASSERT(!function->IsOptimized());
677 }
663 678
664 ZoneScope zone_scope(info->zone(), DELETE_ON_EXIT); 679 // Set the expected number of properties for instances.
680 FunctionLiteral* lit = info->function();
681 int expected = lit->expected_property_count();
682 SetExpectedNofPropertiesFromEstimate(shared, expected);
665 683
666 // The VM is in the COMPILER state until exiting this function. 684 // Set the optimization hints after performing lazy compilation, as
667 VMState state(isolate, COMPILER); 685 // these are not set when the function is set up as a lazily
686 // compiled function.
687 shared->SetThisPropertyAssignmentsInfo(
688 lit->has_only_simple_this_property_assignments(),
689 *lit->this_property_assignments());
668 690
669 PostponeInterruptsScope postpone(isolate); 691 // Check the function has compiled code.
692 ASSERT(shared->is_compiled());
693 shared->set_code_age(0);
694 shared->set_dont_optimize(lit->flags()->Contains(kDontOptimize));
695 shared->set_dont_inline(lit->flags()->Contains(kDontInline));
696 shared->set_ast_node_count(lit->ast_node_count());
670 697
698 if (V8::UseCrankshaft()&&
699 !function.is_null() &&
700 !shared->optimization_disabled()) {
701 // If we're asked to always optimize, we compile the optimized
702 // version of the function right away - unless the debugger is
703 // active as it makes no sense to compile optimized code then.
704 if (FLAG_always_opt &&
705 !Isolate::Current()->DebuggerHasBreakPoints()) {
706 CompilationInfoWithZone optimized(function);
707 optimized.SetOptimizing(AstNode::kNoNumber);
708 return Compiler::CompileLazy(&optimized);
709 }
710 }
711 return true;
712 }
713
714
715 static void InstallCodeCommon(CompilationInfo* info) {
671 Handle<SharedFunctionInfo> shared = info->shared_info(); 716 Handle<SharedFunctionInfo> shared = info->shared_info();
672 int compiled_size = shared->end_position() - shared->start_position(); 717 Handle<Code> code = info->code();
673 isolate->counters()->total_compile_size()->Increment(compiled_size); 718 ASSERT(!code.is_null());
674 719
720 // Set optimizable to false if this is disallowed by the shared
721 // function info, e.g., we might have flushed the code and must
722 // reset this bit when lazy compiling the code again.
723 if (shared->optimization_disabled()) code->set_optimizable(false);
724
725 Handle<JSFunction> function = info->closure();
726 Compiler::RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
727 }
728
729
730 static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
731 Handle<Code> code = info->code();
732 Handle<JSFunction> function = info->closure();
733 if (FLAG_cache_optimized_code && code->kind() == Code::OPTIMIZED_FUNCTION) {
734 Handle<SharedFunctionInfo> shared(function->shared());
735 Handle<FixedArray> literals(function->literals());
736 Handle<Context> global_context(function->context()->global_context());
737 SharedFunctionInfo::AddToOptimizedCodeMap(
738 shared, global_context, code, literals);
739 }
740 }
741
742
743 static bool InstallCodeFromOptimizedCodeMap(CompilationInfo* info) {
675 if (FLAG_cache_optimized_code && info->IsOptimizing()) { 744 if (FLAG_cache_optimized_code && info->IsOptimizing()) {
745 Handle<SharedFunctionInfo> shared = info->shared_info();
676 Handle<JSFunction> function = info->closure(); 746 Handle<JSFunction> function = info->closure();
677 ASSERT(!function.is_null()); 747 ASSERT(!function.is_null());
678 Handle<Context> global_context(function->context()->global_context()); 748 Handle<Context> global_context(function->context()->global_context());
679 int index = shared->SearchOptimizedCodeMap(*global_context); 749 int index = shared->SearchOptimizedCodeMap(*global_context);
680 if (index > 0) { 750 if (index > 0) {
681 if (FLAG_trace_opt) { 751 if (FLAG_trace_opt) {
682 PrintF("[found optimized code for: "); 752 PrintF("[found optimized code for: ");
683 function->PrintName(); 753 function->PrintName();
684 PrintF(" / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(*function)); 754 PrintF(" / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(*function));
685 } 755 }
686 // Caching of optimized code enabled and optimized code found. 756 // Caching of optimized code enabled and optimized code found.
687 shared->InstallFromOptimizedCodeMap(*function, index); 757 shared->InstallFromOptimizedCodeMap(*function, index);
688 return true; 758 return true;
689 } 759 }
690 } 760 }
761 return false;
762 }
763
764
765 bool Compiler::CompileLazy(CompilationInfo* info) {
766 Isolate* isolate = info->isolate();
767
768 ZoneScope zone_scope(info->zone(), DELETE_ON_EXIT);
769
770 // The VM is in the COMPILER state until exiting this function.
771 VMState state(isolate, COMPILER);
772
773 PostponeInterruptsScope postpone(isolate);
774
775 Handle<SharedFunctionInfo> shared = info->shared_info();
776 int compiled_size = shared->end_position() - shared->start_position();
777 isolate->counters()->total_compile_size()->Increment(compiled_size);
778
779 if (InstallCodeFromOptimizedCodeMap(info)) return true;
691 780
692 // Generate the AST for the lazily compiled function. 781 // Generate the AST for the lazily compiled function.
693 if (ParserApi::Parse(info, kNoParsingFlags)) { 782 if (ParserApi::Parse(info, kNoParsingFlags)) {
694 // Measure how long it takes to do the lazy compilation; only take the 783 // Measure how long it takes to do the lazy compilation; only take the
695 // rest of the function into account to avoid overlap with the lazy 784 // rest of the function into account to avoid overlap with the lazy
696 // parsing statistics. 785 // parsing statistics.
697 HistogramTimerScope timer(isolate->counters()->compile_lazy()); 786 HistogramTimerScope timer(isolate->counters()->compile_lazy());
698 787
699 // After parsing we know the function's language mode. Remember it. 788 // After parsing we know the function's language mode. Remember it.
700 LanguageMode language_mode = info->function()->language_mode(); 789 LanguageMode language_mode = info->function()->language_mode();
701 info->SetLanguageMode(language_mode); 790 info->SetLanguageMode(language_mode);
702 shared->set_language_mode(language_mode); 791 shared->set_language_mode(language_mode);
703 792
704 // Compile the code. 793 // Compile the code.
705 if (!MakeCode(info)) { 794 if (!MakeCode(info)) {
706 if (!isolate->has_pending_exception()) { 795 if (!isolate->has_pending_exception()) {
707 isolate->StackOverflow(); 796 isolate->StackOverflow();
708 } 797 }
709 } else { 798 } else {
710 ASSERT(!info->code().is_null()); 799 InstallCodeCommon(info);
711 Handle<Code> code = info->code();
712 // Set optimizable to false if this is disallowed by the shared
713 // function info, e.g., we might have flushed the code and must
714 // reset this bit when lazy compiling the code again.
715 if (shared->optimization_disabled()) code->set_optimizable(false);
716
717 Handle<JSFunction> function = info->closure();
718 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
719 800
720 if (info->IsOptimizing()) { 801 if (info->IsOptimizing()) {
802 Handle<Code> code = info->code();
721 ASSERT(shared->scope_info() != ScopeInfo::Empty()); 803 ASSERT(shared->scope_info() != ScopeInfo::Empty());
722 function->ReplaceCode(*code); 804 info->closure()->ReplaceCode(*code);
723 if (FLAG_cache_optimized_code && 805 InsertCodeIntoOptimizedCodeMap(info);
724 code->kind() == Code::OPTIMIZED_FUNCTION) { 806 return true;
725 Handle<SharedFunctionInfo> shared(function->shared());
726 Handle<FixedArray> literals(function->literals());
727 Handle<Context> global_context(function->context()->global_context());
728 SharedFunctionInfo::AddToOptimizedCodeMap(
729 shared, global_context, code, literals);
730 }
731 } else { 807 } else {
732 // Update the shared function info with the compiled code and the 808 return InstallFullCode(info);
733 // scope info. Please note, that the order of the shared function
734 // info initialization is important since set_scope_info might
735 // trigger a GC, causing the ASSERT below to be invalid if the code
736 // was flushed. By setting the code object last we avoid this.
737 Handle<ScopeInfo> scope_info =
738 ScopeInfo::Create(info->scope(), info->zone());
739 shared->set_scope_info(*scope_info);
740 shared->set_code(*code);
741 if (!function.is_null()) {
742 function->ReplaceCode(*code);
743 ASSERT(!function->IsOptimized());
744 }
745
746 // Set the expected number of properties for instances.
747 FunctionLiteral* lit = info->function();
748 int expected = lit->expected_property_count();
749 SetExpectedNofPropertiesFromEstimate(shared, expected);
750
751 // Set the optimization hints after performing lazy compilation, as
752 // these are not set when the function is set up as a lazily
753 // compiled function.
754 shared->SetThisPropertyAssignmentsInfo(
755 lit->has_only_simple_this_property_assignments(),
756 *lit->this_property_assignments());
757
758 // Check the function has compiled code.
759 ASSERT(shared->is_compiled());
760 shared->set_code_age(0);
761 shared->set_dont_optimize(lit->flags()->Contains(kDontOptimize));
762 shared->set_dont_inline(lit->flags()->Contains(kDontInline));
763 shared->set_dont_cache(lit->flags()->Contains(kDontCache));
764 shared->set_ast_node_count(lit->ast_node_count());
765
766 if (V8::UseCrankshaft()&&
767 !function.is_null() &&
768 !shared->optimization_disabled()) {
769 // If we're asked to always optimize, we compile the optimized
770 // version of the function right away - unless the debugger is
771 // active as it makes no sense to compile optimized code then.
772 if (FLAG_always_opt &&
773 !Isolate::Current()->DebuggerHasBreakPoints()) {
774 CompilationInfoWithZone optimized(function);
775 optimized.SetOptimizing(AstNode::kNoNumber);
776 return CompileLazy(&optimized);
777 }
778 }
779 } 809 }
780
781 return true;
782 } 810 }
783 } 811 }
784 812
785 ASSERT(info->code().is_null()); 813 ASSERT(info->code().is_null());
786 return false; 814 return false;
787 } 815 }
788 816
789 817
818 void Compiler::RecompileParallel(Handle<JSFunction> closure) {
819 ASSERT(!closure->IsInRecompileQueue());
820
821 Isolate* isolate = closure->GetIsolate();
822 if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) {
823 if (FLAG_trace_parallel_recompilation) {
824 PrintF(" ** Compilation queue, will retry opting on next run.\n");
825 }
826 return;
827 }
828
829 SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(closure));
830 VMState state(isolate, PARALLEL_COMPILER_PROLOGUE);
831 PostponeInterruptsScope postpone(isolate);
832
833 Handle<SharedFunctionInfo> shared = info->shared_info();
834 int compiled_size = shared->end_position() - shared->start_position();
835 isolate->counters()->total_compile_size()->Increment(compiled_size);
836 info->SetOptimizing(AstNode::kNoNumber);
837
838 {
839 CompilationHandleScope handle_scope(*info);
840
841 if (InstallCodeFromOptimizedCodeMap(*info)) return;
842
843 if (ParserApi::Parse(*info, kNoParsingFlags)) {
844 LanguageMode language_mode = info->function()->language_mode();
845 info->SetLanguageMode(language_mode);
846 shared->set_language_mode(language_mode);
847 info->SaveHandles();
848
849 if (Rewriter::Rewrite(*info) && Scope::Analyze(*info)) {
850 OptimizingCompiler* compiler =
851 new(info->zone()) OptimizingCompiler(*info);
852 OptimizingCompiler::Status status = compiler->CreateGraph();
853 if (status == OptimizingCompiler::SUCCEEDED) {
854 isolate->optimizing_compiler_thread()->QueueForOptimization(compiler);
855 shared->code()->set_profiler_ticks(0);
856 closure->ReplaceCode(isolate->builtins()->builtin(
857 Builtins::kInRecompileQueue));
858 info.Detach();
859 } else if (status == OptimizingCompiler::BAILED_OUT) {
860 isolate->clear_pending_exception();
861 InstallFullCode(*info);
862 }
863 }
864 }
865 }
866
867 if (isolate->has_pending_exception()) {
868 isolate->clear_pending_exception();
869 }
870 }
871
872
873 void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) {
874 SmartPointer<CompilationInfo> info(optimizing_compiler->info());
875 // If crankshaft succeeded, install the optimized code else install
Yang 2012/07/19 12:47:30 "If crankshaft succeeded, install the optimized co
sanjoy 2012/07/19 15:06:09 Done.
876 // the full code.
877 OptimizingCompiler::Status status = optimizing_compiler->last_status();
878 if (status == OptimizingCompiler::SUCCEEDED) {
879 status = optimizing_compiler->GenerateAndInstallCode();
880 ASSERT(status == OptimizingCompiler::SUCCEEDED ||
881 status == OptimizingCompiler::BAILED_OUT);
882 }
883
884 InstallCodeCommon(*info);
885 if (status == OptimizingCompiler::SUCCEEDED) {
886 Handle<Code> code = info->code();
887 ASSERT(info->shared_info()->scope_info() != ScopeInfo::Empty());
888 info->closure()->ReplaceCode(*code);
889 if (info->shared_info()->SearchOptimizedCodeMap(
890 info->closure()->context()->global_context()) == -1) {
891 InsertCodeIntoOptimizedCodeMap(*info);
892 }
893 } else {
894 info->SetCode(Handle<Code>(info->shared_info()->code()));
895 InstallFullCode(*info);
896 }
897 }
898
899
790 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, 900 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
791 Handle<Script> script) { 901 Handle<Script> script) {
792 // Precondition: code has been parsed and scopes have been analyzed. 902 // Precondition: code has been parsed and scopes have been analyzed.
793 CompilationInfoWithZone info(script); 903 CompilationInfoWithZone info(script);
794 info.SetFunction(literal); 904 info.SetFunction(literal);
795 info.SetScope(literal->scope()); 905 info.SetScope(literal->scope());
796 info.SetLanguageMode(literal->scope()->language_mode()); 906 info.SetLanguageMode(literal->scope()->language_mode());
797 907
798 LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal); 908 LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal);
799 // Determine if the function can be lazily compiled. This is necessary to 909 // Determine if the function can be lazily compiled. This is necessary to
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 } 1021 }
912 } 1022 }
913 1023
914 GDBJIT(AddCode(Handle<String>(shared->DebugName()), 1024 GDBJIT(AddCode(Handle<String>(shared->DebugName()),
915 Handle<Script>(info->script()), 1025 Handle<Script>(info->script()),
916 Handle<Code>(info->code()), 1026 Handle<Code>(info->code()),
917 info)); 1027 info));
918 } 1028 }
919 1029
920 } } // namespace v8::internal 1030 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/d8.h » ('j') | src/execution.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698