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

Side by Side Diff: src/compiler.cc

Issue 1917193007: [compiler] Guard implicit tier-up when ensuring deopt support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased. 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 | « no previous file | no next file » | 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 841 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 } 852 }
853 } else { 853 } else {
854 info->set_osr_frame(osr_frame); 854 info->set_osr_frame(osr_frame);
855 if (GetOptimizedCodeNow(job.get())) return info->code(); 855 if (GetOptimizedCodeNow(job.get())) return info->code();
856 } 856 }
857 857
858 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); 858 if (isolate->has_pending_exception()) isolate->clear_pending_exception();
859 return MaybeHandle<Code>(); 859 return MaybeHandle<Code>();
860 } 860 }
861 861
862 class InterpreterActivationsFinder : public ThreadVisitor { 862 class InterpreterActivationsFinder : public ThreadVisitor,
863 public OptimizedFunctionVisitor {
Yang 2016/04/29 10:19:49 Multiple inheritance. I hope that's fine with the
rmcilroy 2016/04/29 10:50:29 Both classes are pure virtual, which is allowed by
Michael Starzinger 2016/04/29 10:59:10 I don't have a strong opinion on this. Happy to se
863 public: 864 public:
864 SharedFunctionInfo* shared_; 865 SharedFunctionInfo* shared_;
865 bool has_activations_; 866 bool has_activations_;
866 867
867 explicit InterpreterActivationsFinder(SharedFunctionInfo* shared) 868 explicit InterpreterActivationsFinder(SharedFunctionInfo* shared)
868 : shared_(shared), has_activations_(false) {} 869 : shared_(shared), has_activations_(false) {}
869 870
870 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 871 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
871 JavaScriptFrameIterator it(isolate, top); 872 JavaScriptFrameIterator it(isolate, top);
872 for (; !it.done() && !has_activations_; it.Advance()) { 873 for (; !it.done() && !has_activations_; it.Advance()) {
873 JavaScriptFrame* frame = it.frame(); 874 JavaScriptFrame* frame = it.frame();
874 if (!frame->is_interpreted()) continue; 875 if (!frame->is_interpreted()) continue;
875 if (frame->function()->shared() == shared_) has_activations_ = true; 876 if (frame->function()->shared() == shared_) has_activations_ = true;
876 } 877 }
877 } 878 }
879
880 void VisitFunction(JSFunction* function) {
881 if (function->Inlines(shared_)) has_activations_ = true;
Yang 2016/04/29 10:19:49 We could be more precise here and only mark has_ac
Michael Starzinger 2016/04/29 10:59:10 Not sure I understand entirely. The only way optim
882 }
883
884 void EnterContext(Context* context) {}
885 void LeaveContext(Context* context) {}
878 }; 886 };
879 887
880 bool HasInterpreterActivations(Isolate* isolate, SharedFunctionInfo* shared) { 888 bool HasInterpreterActivations(Isolate* isolate, SharedFunctionInfo* shared) {
881 InterpreterActivationsFinder activations_finder(shared); 889 InterpreterActivationsFinder activations_finder(shared);
882 activations_finder.VisitThread(isolate, isolate->thread_local_top()); 890 activations_finder.VisitThread(isolate, isolate->thread_local_top());
883 isolate->thread_manager()->IterateArchivedThreads(&activations_finder); 891 isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
892 if (FLAG_turbo_from_bytecode) {
893 // If we are able to optimize functions directly from bytecode, then there
894 // might be optimized functions that rely on bytecode being around. We need
895 // to prevent switching the given function to baseline code in those cases.
896 Deoptimizer::VisitAllOptimizedFunctions(isolate, &activations_finder);
897 }
884 return activations_finder.has_activations_; 898 return activations_finder.has_activations_;
885 } 899 }
886 900
887 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) { 901 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) {
888 Isolate* isolate = function->GetIsolate(); 902 Isolate* isolate = function->GetIsolate();
889 VMState<COMPILER> state(isolate); 903 VMState<COMPILER> state(isolate);
890 PostponeInterruptsScope postpone(isolate); 904 PostponeInterruptsScope postpone(isolate);
891 Zone zone(isolate->allocator()); 905 Zone zone(isolate->allocator());
892 ParseInfo parse_info(&zone, function); 906 ParseInfo parse_info(&zone, function);
893 CompilationInfo info(&parse_info, function); 907 CompilationInfo info(&parse_info, function);
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 DCHECK(!isolate->has_pending_exception()); 1334 DCHECK(!isolate->has_pending_exception());
1321 return true; 1335 return true;
1322 } 1336 }
1323 1337
1324 // TODO(turbofan): In the future, unoptimized code with deopt support could 1338 // TODO(turbofan): In the future, unoptimized code with deopt support could
1325 // be generated lazily once deopt is triggered. 1339 // be generated lazily once deopt is triggered.
1326 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { 1340 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) {
1327 DCHECK_NOT_NULL(info->literal()); 1341 DCHECK_NOT_NULL(info->literal());
1328 DCHECK_NOT_NULL(info->scope()); 1342 DCHECK_NOT_NULL(info->scope());
1329 Handle<SharedFunctionInfo> shared = info->shared_info(); 1343 Handle<SharedFunctionInfo> shared = info->shared_info();
1330 if (shared->HasBytecodeArray() &&
1331 HasInterpreterActivations(info->isolate(), *shared)) {
1332 // Do not tier up from here if we have bytecode on the stack.
1333 return false;
1334 }
1335 if (!shared->has_deoptimization_support()) { 1344 if (!shared->has_deoptimization_support()) {
1336 Zone zone(info->isolate()->allocator()); 1345 Zone zone(info->isolate()->allocator());
1337 CompilationInfo unoptimized(info->parse_info(), info->closure()); 1346 CompilationInfo unoptimized(info->parse_info(), info->closure());
1338 unoptimized.EnableDeoptimizationSupport(); 1347 unoptimized.EnableDeoptimizationSupport();
1348 // TODO(4280): For now we disable switching to baseline code in the presence
1349 // of interpreter activations of the given function. The reasons are:
1350 // 1) The debugger assumes each function is either full-code or bytecode.
1351 // 2) The underlying bytecode is cleared below, breaking stack unwinding.
1352 // The expensive check for activations only needs to be done when the given
1353 // function has bytecode, otherwise we can be sure there are no activations.
1354 if (shared->HasBytecodeArray() &&
1355 HasInterpreterActivations(info->isolate(), *shared)) {
1356 return false;
1357 }
1339 // If the current code has reloc info for serialization, also include 1358 // If the current code has reloc info for serialization, also include
1340 // reloc info for serialization for the new code, so that deopt support 1359 // reloc info for serialization for the new code, so that deopt support
1341 // can be added without losing IC state. 1360 // can be added without losing IC state.
1342 if (shared->code()->kind() == Code::FUNCTION && 1361 if (shared->code()->kind() == Code::FUNCTION &&
1343 shared->code()->has_reloc_info_for_serialization()) { 1362 shared->code()->has_reloc_info_for_serialization()) {
1344 unoptimized.PrepareForSerializing(); 1363 unoptimized.PrepareForSerializing();
1345 } 1364 }
1346 EnsureFeedbackVector(&unoptimized); 1365 EnsureFeedbackVector(&unoptimized);
1347 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; 1366 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false;
1348 1367
1349 shared->EnableDeoptimizationSupport(*unoptimized.code()); 1368 // TODO(4280): For now we play it safe and remove the bytecode array when we
1369 // switch to baseline code. We might consider keeping around the bytecode so
1370 // that it can be used as the "source of truth" eventually.
1371 shared->ClearBytecodeArray();
1350 1372
1351 // The scope info might not have been set if a lazily compiled 1373 // The scope info might not have been set if a lazily compiled
1352 // function is inlined before being called for the first time. 1374 // function is inlined before being called for the first time.
1353 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { 1375 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) {
1354 InstallSharedScopeInfo(info, shared); 1376 InstallSharedScopeInfo(info, shared);
1355 } 1377 }
1356 1378
1379 // Install compilation result on the shared function info
1380 shared->EnableDeoptimizationSupport(*unoptimized.code());
Yang 2016/04/29 10:19:49 Is there a reason this has been moved to after ins
Michael Starzinger 2016/04/29 10:59:10 No strong reason other than to bring the steps in
1381
1357 // The existing unoptimized code was replaced with the new one. 1382 // The existing unoptimized code was replaced with the new one.
1358 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized); 1383 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized);
1359 } 1384 }
1360 return true; 1385 return true;
1361 } 1386 }
1362 1387
1363 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( 1388 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
1364 Handle<String> source, Handle<SharedFunctionInfo> outer_info, 1389 Handle<String> source, Handle<SharedFunctionInfo> outer_info,
1365 Handle<Context> context, LanguageMode language_mode, 1390 Handle<Context> context, LanguageMode language_mode,
1366 ParseRestriction restriction, int eval_scope_position, int eval_position, 1391 ParseRestriction restriction, int eval_scope_position, int eval_position,
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
1814 MaybeHandle<Code> code; 1839 MaybeHandle<Code> code;
1815 if (cached.code != nullptr) code = handle(cached.code); 1840 if (cached.code != nullptr) code = handle(cached.code);
1816 Handle<Context> native_context(function->context()->native_context()); 1841 Handle<Context> native_context(function->context()->native_context());
1817 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, 1842 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code,
1818 literals, BailoutId::None()); 1843 literals, BailoutId::None());
1819 } 1844 }
1820 } 1845 }
1821 1846
1822 } // namespace internal 1847 } // namespace internal
1823 } // namespace v8 1848 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698