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

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: Fix test for nosnap build 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') | 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 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 if (GetOptimizedCodeNow(job.get())) return info->code(); 782 if (GetOptimizedCodeNow(job.get())) return info->code();
783 } 783 }
784 784
785 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); 785 if (isolate->has_pending_exception()) isolate->clear_pending_exception();
786 return MaybeHandle<Code>(); 786 return MaybeHandle<Code>();
787 } 787 }
788 788
789 class InterpreterActivationsFinder : public ThreadVisitor, 789 class InterpreterActivationsFinder : public ThreadVisitor,
790 public OptimizedFunctionVisitor { 790 public OptimizedFunctionVisitor {
791 public: 791 public:
792 SharedFunctionInfo* shared_;
793 bool has_activations_;
794
795 explicit InterpreterActivationsFinder(SharedFunctionInfo* shared) 792 explicit InterpreterActivationsFinder(SharedFunctionInfo* shared)
796 : shared_(shared), has_activations_(false) {} 793 : shared_(shared), has_activations_(false) {}
797 794
798 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 795 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
796 Address* activation_pc_address = nullptr;
799 JavaScriptFrameIterator it(isolate, top); 797 JavaScriptFrameIterator it(isolate, top);
800 for (; !it.done() && !has_activations_; it.Advance()) { 798 for (; !it.done(); it.Advance()) {
801 JavaScriptFrame* frame = it.frame(); 799 JavaScriptFrame* frame = it.frame();
802 if (!frame->is_interpreted()) continue; 800 if (!frame->is_interpreted()) continue;
803 if (frame->function()->shared() == shared_) has_activations_ = true; 801 if (frame->function()->shared() == shared_) {
802 has_activations_ = true;
803 activation_pc_address = frame->pc_address();
804 }
805 }
806
807 if (activation_pc_address) {
808 activation_pc_addresses_.push_back(activation_pc_address);
804 } 809 }
805 } 810 }
806 811
807 void VisitFunction(JSFunction* function) { 812 void VisitFunction(JSFunction* function) {
808 if (function->Inlines(shared_)) has_activations_ = true; 813 if (function->Inlines(shared_)) has_activations_ = true;
809 } 814 }
810 815
811 void EnterContext(Context* context) {} 816 void EnterContext(Context* context) {}
812 void LeaveContext(Context* context) {} 817 void LeaveContext(Context* context) {}
818
819 bool MarkActivationsForBaselineOnReturn(Isolate* isolate) {
820 if (activation_pc_addresses_.empty()) return false;
821
822 for (Address* activation_pc_address : activation_pc_addresses_) {
823 DCHECK(isolate->inner_pointer_to_code_cache()
824 ->GetCacheEntry(*activation_pc_address)
825 ->code->is_interpreter_trampoline_builtin());
826 *activation_pc_address =
827 isolate->builtins()->InterpreterMarkBaselineOnReturn()->entry();
828 }
829 return true;
830 }
831
832 bool has_activations() { return has_activations_; }
833
834 private:
835 SharedFunctionInfo* shared_;
836 bool has_activations_;
837 std::vector<Address*> activation_pc_addresses_;
813 }; 838 };
814 839
815 bool HasInterpreterActivations(Isolate* isolate, SharedFunctionInfo* shared) { 840 bool HasInterpreterActivations(
816 InterpreterActivationsFinder activations_finder(shared); 841 Isolate* isolate, InterpreterActivationsFinder* activations_finder) {
817 activations_finder.VisitThread(isolate, isolate->thread_local_top()); 842 activations_finder->VisitThread(isolate, isolate->thread_local_top());
818 isolate->thread_manager()->IterateArchivedThreads(&activations_finder); 843 isolate->thread_manager()->IterateArchivedThreads(activations_finder);
819 if (FLAG_turbo_from_bytecode) { 844 if (FLAG_turbo_from_bytecode) {
820 // If we are able to optimize functions directly from bytecode, then there 845 // If we are able to optimize functions directly from bytecode, then there
821 // might be optimized functions that rely on bytecode being around. We need 846 // might be optimized functions that rely on bytecode being around. We need
822 // to prevent switching the given function to baseline code in those cases. 847 // to prevent switching the given function to baseline code in those cases.
823 Deoptimizer::VisitAllOptimizedFunctions(isolate, &activations_finder); 848 Deoptimizer::VisitAllOptimizedFunctions(isolate, activations_finder);
824 } 849 }
825 return activations_finder.has_activations_; 850 return activations_finder->has_activations();
826 } 851 }
827 852
828 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) { 853 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) {
829 Isolate* isolate = function->GetIsolate(); 854 Isolate* isolate = function->GetIsolate();
830 VMState<COMPILER> state(isolate); 855 VMState<COMPILER> state(isolate);
831 PostponeInterruptsScope postpone(isolate); 856 PostponeInterruptsScope postpone(isolate);
832 Zone zone(isolate->allocator()); 857 Zone zone(isolate->allocator());
833 ParseInfo parse_info(&zone, function); 858 ParseInfo parse_info(&zone, function);
834 CompilationInfo info(&parse_info, function); 859 CompilationInfo info(&parse_info, function);
835 860
(...skipping 17 matching lines...) Expand all
853 // there might be suspended activations stored in generator objects on the 878 // there might be suspended activations stored in generator objects on the
854 // heap. We could eventually go directly to TurboFan in this case. 879 // heap. We could eventually go directly to TurboFan in this case.
855 if (function->shared()->is_generator()) { 880 if (function->shared()->is_generator()) {
856 return MaybeHandle<Code>(); 881 return MaybeHandle<Code>();
857 } 882 }
858 883
859 // TODO(4280): For now we disable switching to baseline code in the presence 884 // TODO(4280): For now we disable switching to baseline code in the presence
860 // of interpreter activations of the given function. The reasons are: 885 // of interpreter activations of the given function. The reasons are:
861 // 1) The debugger assumes each function is either full-code or bytecode. 886 // 1) The debugger assumes each function is either full-code or bytecode.
862 // 2) The underlying bytecode is cleared below, breaking stack unwinding. 887 // 2) The underlying bytecode is cleared below, breaking stack unwinding.
863 if (HasInterpreterActivations(isolate, function->shared())) { 888 InterpreterActivationsFinder activations_finder(function->shared());
889 if (HasInterpreterActivations(isolate, &activations_finder)) {
864 if (FLAG_trace_opt) { 890 if (FLAG_trace_opt) {
865 OFStream os(stdout); 891 OFStream os(stdout);
866 os << "[unable to switch " << Brief(*function) << " due to activations]" 892 os << "[unable to switch " << Brief(*function) << " due to activations]"
867 << std::endl; 893 << std::endl;
868 } 894 }
895
896 if (activations_finder.MarkActivationsForBaselineOnReturn(isolate)) {
897 if (FLAG_trace_opt) {
898 OFStream os(stdout);
899 os << "[marking " << Brief(function->shared())
900 << " for baseline recompilation on return]" << std::endl;
901 }
902 }
903
869 return MaybeHandle<Code>(); 904 return MaybeHandle<Code>();
870 } 905 }
871 906
872 if (FLAG_trace_opt) { 907 if (FLAG_trace_opt) {
873 OFStream os(stdout); 908 OFStream os(stdout);
874 os << "[switching method " << Brief(*function) << " to baseline code]" 909 os << "[switching method " << Brief(*function) << " to baseline code]"
875 << std::endl; 910 << std::endl;
876 } 911 }
877 912
878 // Parse and update CompilationInfo with the results. 913 // Parse and update CompilationInfo with the results.
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 // there might be suspended activations stored in generator objects on the 1310 // there might be suspended activations stored in generator objects on the
1276 // heap. We could eventually go directly to TurboFan in this case. 1311 // heap. We could eventually go directly to TurboFan in this case.
1277 if (shared->is_generator()) return false; 1312 if (shared->is_generator()) return false;
1278 1313
1279 // TODO(4280): For now we disable switching to baseline code in the presence 1314 // TODO(4280): For now we disable switching to baseline code in the presence
1280 // of interpreter activations of the given function. The reasons are: 1315 // of interpreter activations of the given function. The reasons are:
1281 // 1) The debugger assumes each function is either full-code or bytecode. 1316 // 1) The debugger assumes each function is either full-code or bytecode.
1282 // 2) The underlying bytecode is cleared below, breaking stack unwinding. 1317 // 2) The underlying bytecode is cleared below, breaking stack unwinding.
1283 // The expensive check for activations only needs to be done when the given 1318 // The expensive check for activations only needs to be done when the given
1284 // function has bytecode, otherwise we can be sure there are no activations. 1319 // function has bytecode, otherwise we can be sure there are no activations.
1285 if (shared->HasBytecodeArray() && 1320 if (shared->HasBytecodeArray()) {
1286 HasInterpreterActivations(info->isolate(), *shared)) { 1321 InterpreterActivationsFinder activations_finder(*shared);
1287 return false; 1322 if (HasInterpreterActivations(info->isolate(), &activations_finder)) {
1323 return false;
1324 }
1288 } 1325 }
1289 1326
1290 // If the current code has reloc info for serialization, also include 1327 // If the current code has reloc info for serialization, also include
1291 // reloc info for serialization for the new code, so that deopt support 1328 // reloc info for serialization for the new code, so that deopt support
1292 // can be added without losing IC state. 1329 // can be added without losing IC state.
1293 if (shared->code()->kind() == Code::FUNCTION && 1330 if (shared->code()->kind() == Code::FUNCTION &&
1294 shared->code()->has_reloc_info_for_serialization()) { 1331 shared->code()->has_reloc_info_for_serialization()) {
1295 unoptimized.PrepareForSerializing(); 1332 unoptimized.PrepareForSerializing();
1296 } 1333 }
1297 EnsureFeedbackVector(&unoptimized); 1334 EnsureFeedbackVector(&unoptimized);
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 MaybeHandle<Code> code; 1793 MaybeHandle<Code> code;
1757 if (cached.code != nullptr) code = handle(cached.code); 1794 if (cached.code != nullptr) code = handle(cached.code);
1758 Handle<Context> native_context(function->context()->native_context()); 1795 Handle<Context> native_context(function->context()->native_context());
1759 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, 1796 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code,
1760 literals, BailoutId::None()); 1797 literals, BailoutId::None());
1761 } 1798 }
1762 } 1799 }
1763 1800
1764 } // namespace internal 1801 } // namespace internal
1765 } // namespace v8 1802 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins.h ('k') | src/frames.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698