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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
59 PARSE_INFO_GETTER_WITH_DEFAULT(LanguageMode, language_mode, STRICT) | 59 PARSE_INFO_GETTER_WITH_DEFAULT(LanguageMode, language_mode, STRICT) |
60 PARSE_INFO_GETTER_WITH_DEFAULT(Handle<JSFunction>, closure, | 60 PARSE_INFO_GETTER_WITH_DEFAULT(Handle<JSFunction>, closure, |
61 Handle<JSFunction>::null()) | 61 Handle<JSFunction>::null()) |
62 PARSE_INFO_GETTER_WITH_DEFAULT(Scope*, scope, nullptr) | 62 PARSE_INFO_GETTER_WITH_DEFAULT(Scope*, scope, nullptr) |
63 PARSE_INFO_GETTER(Handle<Context>, context) | 63 PARSE_INFO_GETTER(Handle<Context>, context) |
64 PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info) | 64 PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info) |
65 | 65 |
66 #undef PARSE_INFO_GETTER | 66 #undef PARSE_INFO_GETTER |
67 #undef PARSE_INFO_GETTER_WITH_DEFAULT | 67 #undef PARSE_INFO_GETTER_WITH_DEFAULT |
68 | 68 |
69 // A wrapper around a CompilationInfo that detaches the Handles from | |
70 // the underlying DeferredHandleScope and stores them in info_ on | |
71 // destruction. | |
72 class CompilationHandleScope BASE_EMBEDDED { | |
73 public: | |
74 explicit CompilationHandleScope(CompilationInfo* info) | |
75 : deferred_(info->isolate()), info_(info) {} | |
76 ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); } | |
77 | |
78 private: | |
79 DeferredHandleScope deferred_; | |
80 CompilationInfo* info_; | |
81 }; | |
69 | 82 |
70 // Exactly like a CompilationInfo, except being allocated via {new} and it also | 83 // Exactly like a CompilationInfo, except being allocated via {new} and it also |
71 // creates and enters a Zone on construction and deallocates it on destruction. | 84 // creates and enters a Zone on construction and deallocates it on destruction. |
72 class CompilationInfoWithZone : public CompilationInfo { | 85 class CompilationInfoWithZone : public CompilationInfo { |
73 public: | 86 public: |
74 explicit CompilationInfoWithZone(Handle<JSFunction> function) | 87 explicit CompilationInfoWithZone(Handle<JSFunction> function) |
75 : CompilationInfo(new ParseInfo(&zone_, function)) {} | 88 : CompilationInfo(new ParseInfo(&zone_, function)) {} |
76 | 89 |
77 // Virtual destructor because a CompilationInfoWithZone has to exit the | 90 // Virtual destructor because a CompilationInfoWithZone has to exit the |
78 // zone scope and get rid of dependent maps even when the destructor is | 91 // zone scope and get rid of dependent maps even when the destructor is |
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
995 info->closure()->ShortPrint(); | 1008 info->closure()->ShortPrint(); |
996 if (info->is_osr()) { | 1009 if (info->is_osr()) { |
997 PrintF(" for concurrent OSR at %d.\n", info->osr_ast_id().ToInt()); | 1010 PrintF(" for concurrent OSR at %d.\n", info->osr_ast_id().ToInt()); |
998 } else { | 1011 } else { |
999 PrintF(" for concurrent optimization.\n"); | 1012 PrintF(" for concurrent optimization.\n"); |
1000 } | 1013 } |
1001 } | 1014 } |
1002 return true; | 1015 return true; |
1003 } | 1016 } |
1004 | 1017 |
1005 | 1018 static MaybeHandle<Code> GetUnoptimizedCode(Handle<JSFunction> function) { |
Benedikt Meurer
2016/03/04 09:54:07
Nit: Place into anonymous instead of adding static
Michael Starzinger
2016/03/04 10:00:04
Done. I also covered two more functions since they
| |
1006 MaybeHandle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) { | |
1007 DCHECK(!function->GetIsolate()->has_pending_exception()); | 1019 DCHECK(!function->GetIsolate()->has_pending_exception()); |
1008 DCHECK(!function->is_compiled()); | 1020 DCHECK(!function->is_compiled()); |
1009 if (function->shared()->is_compiled()) { | 1021 if (function->shared()->is_compiled()) { |
1010 return Handle<Code>(function->shared()->code()); | 1022 return Handle<Code>(function->shared()->code()); |
1011 } | 1023 } |
1012 | 1024 |
1013 CompilationInfoWithZone info(function); | 1025 CompilationInfoWithZone info(function); |
1014 Handle<Code> result; | 1026 Handle<Code> result; |
1015 ASSIGN_RETURN_ON_EXCEPTION(info.isolate(), result, | 1027 ASSIGN_RETURN_ON_EXCEPTION(info.isolate(), result, |
1016 GetUnoptimizedCodeCommon(&info), | 1028 GetUnoptimizedCodeCommon(&info), |
1017 Code); | 1029 Code); |
1018 return result; | 1030 return result; |
1019 } | 1031 } |
1020 | 1032 |
1021 | 1033 static MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { |
1022 MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) { | |
1023 Isolate* isolate = function->GetIsolate(); | 1034 Isolate* isolate = function->GetIsolate(); |
1024 DCHECK(!isolate->has_pending_exception()); | 1035 DCHECK(!isolate->has_pending_exception()); |
1025 DCHECK(!function->is_compiled()); | 1036 DCHECK(!function->is_compiled()); |
1026 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); | 1037 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); |
1027 TRACE_EVENT0("v8", "V8.CompileCode"); | 1038 TRACE_EVENT0("v8", "V8.CompileCode"); |
1028 AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy()); | 1039 AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy()); |
1029 // If the debugger is active, do not compile with turbofan unless we can | 1040 // If the debugger is active, do not compile with turbofan unless we can |
1030 // deopt from turbofan code. | 1041 // deopt from turbofan code. |
1031 if (FLAG_turbo_asm && function->shared()->asm_function() && | 1042 if (FLAG_turbo_asm && function->shared()->asm_function() && |
1032 (FLAG_turbo_asm_deoptimization || !isolate->debug()->is_active()) && | 1043 (FLAG_turbo_asm_deoptimization || !isolate->debug()->is_active()) && |
(...skipping 30 matching lines...) Expand all Loading... | |
1063 result = opt_code; | 1074 result = opt_code; |
1064 } | 1075 } |
1065 } | 1076 } |
1066 | 1077 |
1067 return result; | 1078 return result; |
1068 } | 1079 } |
1069 | 1080 |
1070 | 1081 |
1071 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { | 1082 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { |
1072 if (function->is_compiled()) return true; | 1083 if (function->is_compiled()) return true; |
1073 MaybeHandle<Code> maybe_code = Compiler::GetLazyCode(function); | 1084 MaybeHandle<Code> maybe_code = GetLazyCode(function); |
1074 Handle<Code> code; | 1085 Handle<Code> code; |
1075 if (!maybe_code.ToHandle(&code)) { | 1086 if (!maybe_code.ToHandle(&code)) { |
1076 if (flag == CLEAR_EXCEPTION) { | 1087 if (flag == CLEAR_EXCEPTION) { |
1077 function->GetIsolate()->clear_pending_exception(); | 1088 function->GetIsolate()->clear_pending_exception(); |
1078 } | 1089 } |
1079 return false; | 1090 return false; |
1080 } | 1091 } |
1092 DCHECK(code->IsJavaScriptCode()); | |
1081 function->ReplaceCode(*code); | 1093 function->ReplaceCode(*code); |
1082 DCHECK(function->is_compiled()); | 1094 DCHECK(function->is_compiled()); |
1083 return true; | 1095 return true; |
1084 } | 1096 } |
1085 | 1097 |
1098 bool Compiler::CompileOptimized(Handle<JSFunction> function, | |
1099 ConcurrencyMode mode) { | |
1100 Handle<Code> code; | |
1101 if (Compiler::GetOptimizedCode(function, mode).ToHandle(&code)) { | |
1102 // Optimization succeeded, return optimized code. | |
1103 function->ReplaceCode(*code); | |
1104 } else { | |
1105 // Optimization failed, get unoptimized code. | |
1106 Isolate* isolate = function->GetIsolate(); | |
1107 if (isolate->has_pending_exception()) { // Possible stack overflow. | |
1108 return false; | |
1109 } | |
1110 code = Handle<Code>(function->shared()->code(), isolate); | |
1111 if (code->kind() != Code::FUNCTION && | |
1112 code->kind() != Code::OPTIMIZED_FUNCTION) { | |
1113 if (!GetUnoptimizedCode(function).ToHandle(&code)) { | |
1114 return false; | |
1115 } | |
1116 } | |
1117 function->ReplaceCode(*code); | |
1118 } | |
1119 | |
1120 DCHECK(function->code()->kind() == Code::FUNCTION || | |
1121 function->code()->kind() == Code::OPTIMIZED_FUNCTION || | |
1122 (function->code()->is_interpreter_entry_trampoline() && | |
1123 function->shared()->HasBytecodeArray()) || | |
1124 function->IsInOptimizationQueue()); | |
1125 return true; | |
1126 } | |
1086 | 1127 |
1087 // TODO(turbofan): In the future, unoptimized code with deopt support could | 1128 // TODO(turbofan): In the future, unoptimized code with deopt support could |
1088 // be generated lazily once deopt is triggered. | 1129 // be generated lazily once deopt is triggered. |
1089 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 1130 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
1090 DCHECK_NOT_NULL(info->literal()); | 1131 DCHECK_NOT_NULL(info->literal()); |
1091 DCHECK(info->has_scope()); | 1132 DCHECK(info->has_scope()); |
1092 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1133 Handle<SharedFunctionInfo> shared = info->shared_info(); |
1093 if (!shared->has_deoptimization_support()) { | 1134 if (!shared->has_deoptimization_support()) { |
1094 // TODO(titzer): just reuse the ParseInfo for the unoptimized compile. | 1135 // TODO(titzer): just reuse the ParseInfo for the unoptimized compile. |
1095 CompilationInfoWithZone unoptimized(info->closure()); | 1136 CompilationInfoWithZone unoptimized(info->closure()); |
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1859 | 1900 |
1860 #if DEBUG | 1901 #if DEBUG |
1861 void CompilationInfo::PrintAstForTesting() { | 1902 void CompilationInfo::PrintAstForTesting() { |
1862 PrintF("--- Source from AST ---\n%s\n", | 1903 PrintF("--- Source from AST ---\n%s\n", |
1863 PrettyPrinter(isolate()).PrintProgram(literal())); | 1904 PrettyPrinter(isolate()).PrintProgram(literal())); |
1864 } | 1905 } |
1865 #endif | 1906 #endif |
1866 | 1907 |
1867 } // namespace internal | 1908 } // namespace internal |
1868 } // namespace v8 | 1909 } // namespace v8 |
OLD | NEW |