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

Side by Side Diff: src/compiler.cc

Issue 2475203003: [compiler] Remove --ignition-preserve-bytecode flag. (Closed)
Patch Set: Created 4 years, 1 month 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/x87/builtins-x87.cc ('k') | src/flag-definitions.h » ('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 #include <memory> 8 #include <memory>
9 9
10 #include "src/asmjs/asm-js.h" 10 #include "src/asmjs/asm-js.h"
11 #include "src/asmjs/asm-typer.h" 11 #include "src/asmjs/asm-typer.h"
12 #include "src/ast/ast-numbering.h" 12 #include "src/ast/ast-numbering.h"
13 #include "src/ast/prettyprinter.h" 13 #include "src/ast/prettyprinter.h"
14 #include "src/ast/scopes.h" 14 #include "src/ast/scopes.h"
15 #include "src/bootstrapper.h" 15 #include "src/bootstrapper.h"
16 #include "src/codegen.h" 16 #include "src/codegen.h"
17 #include "src/compilation-cache.h" 17 #include "src/compilation-cache.h"
18 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" 18 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
19 #include "src/compiler/pipeline.h" 19 #include "src/compiler/pipeline.h"
20 #include "src/crankshaft/hydrogen.h" 20 #include "src/crankshaft/hydrogen.h"
21 #include "src/debug/debug.h" 21 #include "src/debug/debug.h"
22 #include "src/debug/liveedit.h" 22 #include "src/debug/liveedit.h"
23 #include "src/deoptimizer.h"
24 #include "src/frames-inl.h" 23 #include "src/frames-inl.h"
25 #include "src/full-codegen/full-codegen.h" 24 #include "src/full-codegen/full-codegen.h"
26 #include "src/globals.h" 25 #include "src/globals.h"
27 #include "src/heap/heap.h" 26 #include "src/heap/heap.h"
28 #include "src/interpreter/interpreter.h" 27 #include "src/interpreter/interpreter.h"
29 #include "src/isolate-inl.h" 28 #include "src/isolate-inl.h"
30 #include "src/log-inl.h" 29 #include "src/log-inl.h"
31 #include "src/messages.h" 30 #include "src/messages.h"
32 #include "src/parsing/parser.h" 31 #include "src/parsing/parser.h"
33 #include "src/parsing/rewriter.h" 32 #include "src/parsing/rewriter.h"
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 DCHECK(job->state() == CompilationJob::State::kFailed); 770 DCHECK(job->state() == CompilationJob::State::kFailed);
772 if (FLAG_trace_opt) { 771 if (FLAG_trace_opt) {
773 PrintF("[aborted optimizing "); 772 PrintF("[aborted optimizing ");
774 info->closure()->ShortPrint(); 773 info->closure()->ShortPrint();
775 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); 774 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason()));
776 } 775 }
777 info->closure()->ReplaceCode(shared->code()); 776 info->closure()->ReplaceCode(shared->code());
778 return CompilationJob::FAILED; 777 return CompilationJob::FAILED;
779 } 778 }
780 779
781 class InterpreterActivationsFinder : public ThreadVisitor,
782 public OptimizedFunctionVisitor {
783 public:
784 explicit InterpreterActivationsFinder(SharedFunctionInfo* shared)
785 : shared_(shared), has_activations_(false) {}
786
787 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
788 Address* activation_pc_address = nullptr;
789 JavaScriptFrameIterator it(isolate, top);
790 for (; !it.done(); it.Advance()) {
791 JavaScriptFrame* frame = it.frame();
792 if (FLAG_ignition_osr && frame->is_optimized() &&
793 frame->function()->shared() == shared_) {
794 // There might be optimized OSR code active on the stack that is not
795 // reachable through a function. We count this as an activation.
796 has_activations_ = true;
797 }
798 if (frame->is_interpreted() && frame->function()->shared() == shared_) {
799 has_activations_ = true;
800 activation_pc_address = frame->pc_address();
801 }
802 }
803
804 if (activation_pc_address) {
805 activation_pc_addresses_.push_back(activation_pc_address);
806 }
807 }
808
809 void VisitFunction(JSFunction* function) {
810 if (function->Inlines(shared_)) has_activations_ = true;
811 }
812
813 void EnterContext(Context* context) {}
814 void LeaveContext(Context* context) {}
815
816 bool MarkActivationsForBaselineOnReturn(Isolate* isolate) {
817 if (activation_pc_addresses_.empty()) return false;
818
819 for (Address* activation_pc_address : activation_pc_addresses_) {
820 DCHECK(isolate->inner_pointer_to_code_cache()
821 ->GetCacheEntry(*activation_pc_address)
822 ->code->is_interpreter_trampoline_builtin());
823 *activation_pc_address =
824 isolate->builtins()->InterpreterMarkBaselineOnReturn()->entry();
825 }
826 return true;
827 }
828
829 bool has_activations() { return has_activations_; }
830
831 private:
832 SharedFunctionInfo* shared_;
833 bool has_activations_;
834 std::vector<Address*> activation_pc_addresses_;
835 };
836
837 bool HasInterpreterActivations(
838 Isolate* isolate, InterpreterActivationsFinder* activations_finder) {
839 activations_finder->VisitThread(isolate, isolate->thread_local_top());
840 isolate->thread_manager()->IterateArchivedThreads(activations_finder);
841 // There might be optimized functions that rely on bytecode being around. We
842 // need to prevent switching the given function to baseline code.
843 Deoptimizer::VisitAllOptimizedFunctions(isolate, activations_finder);
844 return activations_finder->has_activations();
845 }
846
847 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) { 780 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) {
848 Isolate* isolate = function->GetIsolate(); 781 Isolate* isolate = function->GetIsolate();
849 VMState<COMPILER> state(isolate); 782 VMState<COMPILER> state(isolate);
850 PostponeInterruptsScope postpone(isolate); 783 PostponeInterruptsScope postpone(isolate);
851 Zone zone(isolate->allocator(), ZONE_NAME); 784 Zone zone(isolate->allocator(), ZONE_NAME);
852 ParseInfo parse_info(&zone, handle(function->shared())); 785 ParseInfo parse_info(&zone, handle(function->shared()));
853 CompilationInfo info(&parse_info, function); 786 CompilationInfo info(&parse_info, function);
854 787
855 // Function no longer needs to be tiered up 788 // Function no longer needs to be tiered up
856 function->shared()->set_marked_for_tier_up(false); 789 function->shared()->set_marked_for_tier_up(false);
(...skipping 10 matching lines...) Expand all
867 800
868 // We do not switch to baseline code when the debugger might have created a 801 // We do not switch to baseline code when the debugger might have created a
869 // copy of the bytecode with break slots to be able to set break points. 802 // copy of the bytecode with break slots to be able to set break points.
870 if (function->shared()->HasDebugInfo()) { 803 if (function->shared()->HasDebugInfo()) {
871 return MaybeHandle<Code>(); 804 return MaybeHandle<Code>();
872 } 805 }
873 806
874 // TODO(4280): For now we do not switch generators or async functions to 807 // TODO(4280): For now we do not switch generators or async functions to
875 // baseline code because there might be suspended activations stored in 808 // baseline code because there might be suspended activations stored in
876 // generator objects on the heap. We could eventually go directly to 809 // generator objects on the heap. We could eventually go directly to
877 // TurboFan in this case. 810 // TurboFan in this case.
rmcilroy 2016/11/04 14:23:34 Do we want to do anything about this? I don't thin
Michael Starzinger 2016/11/04 14:27:52 Acknowledged. At first glance I agree with you. Th
878 if (IsResumableFunction(function->shared()->kind())) { 811 if (IsResumableFunction(function->shared()->kind())) {
879 return MaybeHandle<Code>(); 812 return MaybeHandle<Code>();
880 } 813 }
881 814
882 // TODO(4280): For now we disable switching to baseline code in the presence
883 // of interpreter activations of the given function. The reasons is that the
884 // underlying bytecode is cleared below. Note that this only applies in case
885 // the --ignition-preserve-bytecode flag is not passed.
886 if (!FLAG_ignition_preserve_bytecode) {
887 InterpreterActivationsFinder activations_finder(function->shared());
888 if (HasInterpreterActivations(isolate, &activations_finder)) {
889 if (FLAG_trace_opt) {
890 OFStream os(stdout);
891 os << "[unable to switch " << Brief(*function) << " due to activations]"
892 << std::endl;
893 }
894
895 if (activations_finder.MarkActivationsForBaselineOnReturn(isolate)) {
896 if (FLAG_trace_opt) {
897 OFStream os(stdout);
898 os << "[marking " << Brief(function->shared())
899 << " for baseline recompilation on return]" << std::endl;
900 }
901 }
902
903 return MaybeHandle<Code>();
904 }
905 }
906
907 if (FLAG_trace_opt) { 815 if (FLAG_trace_opt) {
908 OFStream os(stdout); 816 OFStream os(stdout);
909 os << "[switching method " << Brief(*function) << " to baseline code]" 817 os << "[switching method " << Brief(*function) << " to baseline code]"
910 << std::endl; 818 << std::endl;
911 } 819 }
912 820
913 // Parse and update CompilationInfo with the results. 821 // Parse and update CompilationInfo with the results.
914 if (!Parser::ParseStatic(info.parse_info())) return MaybeHandle<Code>(); 822 if (!Parser::ParseStatic(info.parse_info())) return MaybeHandle<Code>();
915 Handle<SharedFunctionInfo> shared = info.shared_info(); 823 Handle<SharedFunctionInfo> shared = info.shared_info();
916 DCHECK_EQ(shared->language_mode(), info.literal()->language_mode()); 824 DCHECK_EQ(shared->language_mode(), info.literal()->language_mode());
917 825
918 // Compile baseline code using the full code generator. 826 // Compile baseline code using the full code generator.
919 if (!Compiler::Analyze(info.parse_info()) || 827 if (!Compiler::Analyze(info.parse_info()) ||
920 !FullCodeGenerator::MakeCode(&info)) { 828 !FullCodeGenerator::MakeCode(&info)) {
921 if (!isolate->has_pending_exception()) isolate->StackOverflow(); 829 if (!isolate->has_pending_exception()) isolate->StackOverflow();
922 return MaybeHandle<Code>(); 830 return MaybeHandle<Code>();
923 } 831 }
924 832
925 // TODO(4280): For now we play it safe and remove the bytecode array when we
926 // switch to baseline code. We might consider keeping around the bytecode so
927 // that it can be used as the "source of truth" eventually. Note that this
928 // only applies in case the --ignition-preserve-bytecode flag is not passed.
929 if (!FLAG_ignition_preserve_bytecode) shared->ClearBytecodeArray();
930
931 // Update the shared function info with the scope info. 833 // Update the shared function info with the scope info.
932 InstallSharedScopeInfo(&info, shared); 834 InstallSharedScopeInfo(&info, shared);
933 835
934 // Install compilation result on the shared function info 836 // Install compilation result on the shared function info
935 InstallSharedCompilationResult(&info, shared); 837 InstallSharedCompilationResult(&info, shared);
936 838
937 // Record the function compilation event. 839 // Record the function compilation event.
938 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, &info); 840 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, &info);
939 841
940 return info.code(); 842 return info.code();
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 Zone zone(info->isolate()->allocator(), ZONE_NAME); 1207 Zone zone(info->isolate()->allocator(), ZONE_NAME);
1306 CompilationInfo unoptimized(info->parse_info(), info->closure()); 1208 CompilationInfo unoptimized(info->parse_info(), info->closure());
1307 unoptimized.EnableDeoptimizationSupport(); 1209 unoptimized.EnableDeoptimizationSupport();
1308 1210
1309 // TODO(4280): For now we do not switch generators or async functions to 1211 // TODO(4280): For now we do not switch generators or async functions to
1310 // baseline code because there might be suspended activations stored in 1212 // baseline code because there might be suspended activations stored in
1311 // generator objects on the heap. We could eventually go directly to 1213 // generator objects on the heap. We could eventually go directly to
1312 // TurboFan in this case. 1214 // TurboFan in this case.
1313 if (IsResumableFunction(shared->kind())) return false; 1215 if (IsResumableFunction(shared->kind())) return false;
1314 1216
1315 // TODO(4280): For now we disable switching to baseline code in the presence
1316 // of interpreter activations of the given function. The reasons is that the
1317 // underlying bytecode is cleared below. The expensive check for activations
1318 // only needs to be done when the given function has bytecode, otherwise we
1319 // can be sure there are no activations. Note that this only applies in case
1320 // the --ignition-preserve-bytecode flag is not passed.
1321 if (!FLAG_ignition_preserve_bytecode && shared->HasBytecodeArray()) {
1322 InterpreterActivationsFinder activations_finder(*shared);
1323 if (HasInterpreterActivations(info->isolate(), &activations_finder)) {
1324 return false;
1325 }
1326 }
1327
1328 // When we call PrepareForSerializing below, we will change the shared 1217 // When we call PrepareForSerializing below, we will change the shared
1329 // ParseInfo. Make sure to reset it. 1218 // ParseInfo. Make sure to reset it.
1330 bool old_will_serialize_value = info->parse_info()->will_serialize(); 1219 bool old_will_serialize_value = info->parse_info()->will_serialize();
1331 1220
1332 // If the current code has reloc info for serialization, also include 1221 // If the current code has reloc info for serialization, also include
1333 // reloc info for serialization for the new code, so that deopt support 1222 // reloc info for serialization for the new code, so that deopt support
1334 // can be added without losing IC state. 1223 // can be added without losing IC state.
1335 if (shared->code()->kind() == Code::FUNCTION && 1224 if (shared->code()->kind() == Code::FUNCTION &&
1336 shared->code()->has_reloc_info_for_serialization()) { 1225 shared->code()->has_reloc_info_for_serialization()) {
1337 unoptimized.PrepareForSerializing(); 1226 unoptimized.PrepareForSerializing();
1338 } 1227 }
1339 EnsureFeedbackMetadata(&unoptimized); 1228 EnsureFeedbackMetadata(&unoptimized);
1340 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; 1229 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false;
1341 1230
1342 info->parse_info()->set_will_serialize(old_will_serialize_value); 1231 info->parse_info()->set_will_serialize(old_will_serialize_value);
1343 1232
1344 // TODO(4280): For now we play it safe and remove the bytecode array when we
1345 // switch to baseline code. We might consider keeping around the bytecode so
1346 // that it can be used as the "source of truth" eventually. Note that this
1347 // only applies in case the --ignition-preserve-bytecode flag is not passed.
1348 if (!FLAG_ignition_preserve_bytecode && shared->HasBytecodeArray()) {
1349 shared->ClearBytecodeArray();
1350 }
1351
1352 // The scope info might not have been set if a lazily compiled 1233 // The scope info might not have been set if a lazily compiled
1353 // function is inlined before being called for the first time. 1234 // function is inlined before being called for the first time.
1354 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { 1235 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) {
1355 InstallSharedScopeInfo(info, shared); 1236 InstallSharedScopeInfo(info, shared);
1356 } 1237 }
1357 1238
1358 // Install compilation result on the shared function info 1239 // Install compilation result on the shared function info
1359 shared->EnableDeoptimizationSupport(*unoptimized.code()); 1240 shared->EnableDeoptimizationSupport(*unoptimized.code());
1360 1241
1361 // The existing unoptimized code was replaced with the new one. 1242 // The existing unoptimized code was replaced with the new one.
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
1824 DCHECK(shared->is_compiled()); 1705 DCHECK(shared->is_compiled());
1825 function->set_literals(cached.literals); 1706 function->set_literals(cached.literals);
1826 } else if (shared->is_compiled()) { 1707 } else if (shared->is_compiled()) {
1827 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. 1708 // TODO(mvstanton): pass pretenure flag to EnsureLiterals.
1828 JSFunction::EnsureLiterals(function); 1709 JSFunction::EnsureLiterals(function);
1829 } 1710 }
1830 } 1711 }
1831 1712
1832 } // namespace internal 1713 } // namespace internal
1833 } // namespace v8 1714 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/x87/builtins-x87.cc ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698