| 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 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |