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

Side by Side Diff: src/compiler.cc

Issue 1965343002: [Interpreter] Support compiling for baseline on return from interpreted function. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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
« no previous file with comments | « src/builtins.h ('k') | src/frames.cc » ('j') | src/objects-inl.h » ('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 // 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 767 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 if (GetOptimizedCodeNow(job.get())) return info->code(); 778 if (GetOptimizedCodeNow(job.get())) return info->code();
779 } 779 }
780 780
781 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); 781 if (isolate->has_pending_exception()) isolate->clear_pending_exception();
782 return MaybeHandle<Code>(); 782 return MaybeHandle<Code>();
783 } 783 }
784 784
785 class InterpreterActivationsFinder : public ThreadVisitor, 785 class InterpreterActivationsFinder : public ThreadVisitor,
786 public OptimizedFunctionVisitor { 786 public OptimizedFunctionVisitor {
787 public: 787 public:
788 SharedFunctionInfo* shared_;
789 bool has_activations_;
790
791 explicit InterpreterActivationsFinder(SharedFunctionInfo* shared) 788 explicit InterpreterActivationsFinder(SharedFunctionInfo* shared)
792 : shared_(shared), has_activations_(false) {} 789 : shared_(shared), has_activations_(false) {}
793 790
794 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 791 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
792 Address* activation_pc_address = nullptr;
795 JavaScriptFrameIterator it(isolate, top); 793 JavaScriptFrameIterator it(isolate, top);
796 for (; !it.done() && !has_activations_; it.Advance()) { 794 for (; !it.done(); it.Advance()) {
797 JavaScriptFrame* frame = it.frame(); 795 JavaScriptFrame* frame = it.frame();
798 if (!frame->is_interpreted()) continue; 796 if (!frame->is_interpreted()) continue;
799 if (frame->function()->shared() == shared_) has_activations_ = true; 797 if (frame->function()->shared() == shared_) {
798 has_activations_ = true;
799 activation_pc_address = frame->pc_address();
800 }
801 }
802
803 if (activation_pc_address) {
804 activation_pc_addresses_.push_back(activation_pc_address);
800 } 805 }
801 } 806 }
802 807
803 void VisitFunction(JSFunction* function) { 808 void VisitFunction(JSFunction* function) {
804 if (function->Inlines(shared_)) has_activations_ = true; 809 if (function->Inlines(shared_)) has_activations_ = true;
805 } 810 }
806 811
807 void EnterContext(Context* context) {} 812 void EnterContext(Context* context) {}
808 void LeaveContext(Context* context) {} 813 void LeaveContext(Context* context) {}
814
815 bool MarkActivationsForBaselineOnReturn(Isolate* isolate) {
816 if (activation_pc_addresses_.empty()) return false;
817
818 for (Address* activation_pc_address : activation_pc_addresses_) {
819 DCHECK(isolate->inner_pointer_to_code_cache()
820 ->GetCacheEntry(*activation_pc_address)
821 ->code->is_interpreter_trampoline_builtin());
822 *activation_pc_address =
823 isolate->builtins()->InterpreterMarkBaselineOnReturn()->entry();
824 }
825 return true;
826 }
827
828 bool has_activations() { return has_activations_; }
829
830 private:
831 SharedFunctionInfo* shared_;
832 bool has_activations_;
833 std::vector<Address*> activation_pc_addresses_;
809 }; 834 };
810 835
811 bool HasInterpreterActivations(Isolate* isolate, SharedFunctionInfo* shared) { 836 bool HasInterpreterActivations(
812 InterpreterActivationsFinder activations_finder(shared); 837 Isolate* isolate, InterpreterActivationsFinder* activations_finder) {
813 activations_finder.VisitThread(isolate, isolate->thread_local_top()); 838 activations_finder->VisitThread(isolate, isolate->thread_local_top());
814 isolate->thread_manager()->IterateArchivedThreads(&activations_finder); 839 isolate->thread_manager()->IterateArchivedThreads(activations_finder);
815 if (FLAG_turbo_from_bytecode) { 840 if (FLAG_turbo_from_bytecode) {
816 // If we are able to optimize functions directly from bytecode, then there 841 // If we are able to optimize functions directly from bytecode, then there
817 // might be optimized functions that rely on bytecode being around. We need 842 // might be optimized functions that rely on bytecode being around. We need
818 // to prevent switching the given function to baseline code in those cases. 843 // to prevent switching the given function to baseline code in those cases.
819 Deoptimizer::VisitAllOptimizedFunctions(isolate, &activations_finder); 844 Deoptimizer::VisitAllOptimizedFunctions(isolate, activations_finder);
820 } 845 }
821 return activations_finder.has_activations_; 846 return activations_finder->has_activations();
822 } 847 }
823 848
824 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) { 849 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) {
825 Isolate* isolate = function->GetIsolate(); 850 Isolate* isolate = function->GetIsolate();
826 VMState<COMPILER> state(isolate); 851 VMState<COMPILER> state(isolate);
827 PostponeInterruptsScope postpone(isolate); 852 PostponeInterruptsScope postpone(isolate);
828 Zone zone(isolate->allocator()); 853 Zone zone(isolate->allocator());
829 ParseInfo parse_info(&zone, function); 854 ParseInfo parse_info(&zone, function);
830 CompilationInfo info(&parse_info, function); 855 CompilationInfo info(&parse_info, function);
831 856
(...skipping 17 matching lines...) Expand all
849 // there might be suspended activations stored in generator objects on the 874 // there might be suspended activations stored in generator objects on the
850 // heap. We could eventually go directly to TurboFan in this case. 875 // heap. We could eventually go directly to TurboFan in this case.
851 if (function->shared()->is_generator()) { 876 if (function->shared()->is_generator()) {
852 return MaybeHandle<Code>(); 877 return MaybeHandle<Code>();
853 } 878 }
854 879
855 // TODO(4280): For now we disable switching to baseline code in the presence 880 // TODO(4280): For now we disable switching to baseline code in the presence
856 // of interpreter activations of the given function. The reasons are: 881 // of interpreter activations of the given function. The reasons are:
857 // 1) The debugger assumes each function is either full-code or bytecode. 882 // 1) The debugger assumes each function is either full-code or bytecode.
858 // 2) The underlying bytecode is cleared below, breaking stack unwinding. 883 // 2) The underlying bytecode is cleared below, breaking stack unwinding.
859 if (HasInterpreterActivations(isolate, function->shared())) { 884 InterpreterActivationsFinder activations_finder(function->shared());
885 if (HasInterpreterActivations(isolate, &activations_finder)) {
860 if (FLAG_trace_opt) { 886 if (FLAG_trace_opt) {
861 OFStream os(stdout); 887 OFStream os(stdout);
862 os << "[unable to switch " << Brief(*function) << " due to activations]" 888 os << "[unable to switch " << Brief(*function) << " due to activations]"
863 << std::endl; 889 << std::endl;
864 } 890 }
891
892 if (activations_finder.MarkActivationsForBaselineOnReturn(isolate)) {
893 if (FLAG_trace_opt) {
894 OFStream os(stdout);
895 os << "[marking " << Brief(*function) << " for baseline recompilation "
Michael Starzinger 2016/05/11 13:04:27 nit: Let's print s/*function/function->shared()/ h
rmcilroy 2016/05/12 13:11:47 Done. This brings up the point of whether we shoul
Michael Starzinger 2016/05/13 09:01:39 Hmm. Interesting idea. I suppose it would be possi
rmcilroy 2016/05/17 11:28:30 Yes absolutely, only in a separate CL and if it's
896 << "on return]" << std::endl;
897 }
898 }
899
865 return MaybeHandle<Code>(); 900 return MaybeHandle<Code>();
866 } 901 }
867 902
868 if (FLAG_trace_opt) { 903 if (FLAG_trace_opt) {
869 OFStream os(stdout); 904 OFStream os(stdout);
870 os << "[switching method " << Brief(*function) << " to baseline code]" 905 os << "[switching method " << Brief(*function) << " to baseline code]"
871 << std::endl; 906 << std::endl;
872 } 907 }
873 908
874 // Parse and update CompilationInfo with the results. 909 // Parse and update CompilationInfo with the results.
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 // TODO(turbofan): In the future, unoptimized code with deopt support could 1279 // TODO(turbofan): In the future, unoptimized code with deopt support could
1245 // be generated lazily once deopt is triggered. 1280 // be generated lazily once deopt is triggered.
1246 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { 1281 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) {
1247 DCHECK_NOT_NULL(info->literal()); 1282 DCHECK_NOT_NULL(info->literal());
1248 DCHECK_NOT_NULL(info->scope()); 1283 DCHECK_NOT_NULL(info->scope());
1249 Handle<SharedFunctionInfo> shared = info->shared_info(); 1284 Handle<SharedFunctionInfo> shared = info->shared_info();
1250 if (!shared->has_deoptimization_support()) { 1285 if (!shared->has_deoptimization_support()) {
1251 Zone zone(info->isolate()->allocator()); 1286 Zone zone(info->isolate()->allocator());
1252 CompilationInfo unoptimized(info->parse_info(), info->closure()); 1287 CompilationInfo unoptimized(info->parse_info(), info->closure());
1253 unoptimized.EnableDeoptimizationSupport(); 1288 unoptimized.EnableDeoptimizationSupport();
1289
1254 // TODO(4280): For now we disable switching to baseline code in the presence 1290 // TODO(4280): For now we disable switching to baseline code in the presence
1255 // of interpreter activations of the given function. The reasons are: 1291 // of interpreter activations of the given function. The reasons are:
1256 // 1) The debugger assumes each function is either full-code or bytecode. 1292 // 1) The debugger assumes each function is either full-code or bytecode.
1257 // 2) The underlying bytecode is cleared below, breaking stack unwinding. 1293 // 2) The underlying bytecode is cleared below, breaking stack unwinding.
1258 // The expensive check for activations only needs to be done when the given 1294 // The expensive check for activations only needs to be done when the given
1259 // function has bytecode, otherwise we can be sure there are no activations. 1295 // function has bytecode, otherwise we can be sure there are no activations.
1260 if (shared->HasBytecodeArray() && 1296 if (shared->HasBytecodeArray()) {
1261 HasInterpreterActivations(info->isolate(), *shared)) { 1297 InterpreterActivationsFinder activations_finder(*shared);
1262 return false; 1298 if (HasInterpreterActivations(info->isolate(), &activations_finder)) {
1299 return false;
1300 }
1263 } 1301 }
1264 // If the current code has reloc info for serialization, also include 1302 // If the current code has reloc info for serialization, also include
1265 // reloc info for serialization for the new code, so that deopt support 1303 // reloc info for serialization for the new code, so that deopt support
1266 // can be added without losing IC state. 1304 // can be added without losing IC state.
1267 if (shared->code()->kind() == Code::FUNCTION && 1305 if (shared->code()->kind() == Code::FUNCTION &&
1268 shared->code()->has_reloc_info_for_serialization()) { 1306 shared->code()->has_reloc_info_for_serialization()) {
1269 unoptimized.PrepareForSerializing(); 1307 unoptimized.PrepareForSerializing();
1270 } 1308 }
1271 EnsureFeedbackVector(&unoptimized); 1309 EnsureFeedbackVector(&unoptimized);
1272 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; 1310 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false;
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
1743 MaybeHandle<Code> code; 1781 MaybeHandle<Code> code;
1744 if (cached.code != nullptr) code = handle(cached.code); 1782 if (cached.code != nullptr) code = handle(cached.code);
1745 Handle<Context> native_context(function->context()->native_context()); 1783 Handle<Context> native_context(function->context()->native_context());
1746 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, 1784 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code,
1747 literals, BailoutId::None()); 1785 literals, BailoutId::None());
1748 } 1786 }
1749 } 1787 }
1750 1788
1751 } // namespace internal 1789 } // namespace internal
1752 } // namespace v8 1790 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins.h ('k') | src/frames.cc » ('j') | src/objects-inl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698