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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing(); | 123 if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing(); |
124 if (FLAG_turbo_inlining) MarkAsInliningEnabled(); | 124 if (FLAG_turbo_inlining) MarkAsInliningEnabled(); |
125 if (FLAG_turbo_source_positions) MarkAsSourcePositionsEnabled(); | 125 if (FLAG_turbo_source_positions) MarkAsSourcePositionsEnabled(); |
126 if (FLAG_turbo_splitting) MarkAsSplittingEnabled(); | 126 if (FLAG_turbo_splitting) MarkAsSplittingEnabled(); |
127 if (FLAG_turbo_types) MarkAsTypingEnabled(); | 127 if (FLAG_turbo_types) MarkAsTypingEnabled(); |
128 | 128 |
129 if (has_shared_info()) { | 129 if (has_shared_info()) { |
130 if (shared_info()->is_compiled()) { | 130 if (shared_info()->is_compiled()) { |
131 // We should initialize the CompilationInfo feedback vector from the | 131 // We should initialize the CompilationInfo feedback vector from the |
132 // passed in shared info, rather than creating a new one. | 132 // passed in shared info, rather than creating a new one. |
133 feedback_vector_ = Handle<TypeFeedbackVector>( | 133 feedback_metadata_ = Handle<TypeFeedbackMetadata>( |
134 shared_info()->feedback_vector(), parse_info->isolate()); | 134 shared_info()->feedback_metadata(), parse_info->isolate()); |
135 } | 135 } |
136 if (shared_info()->never_compiled()) MarkAsFirstCompile(); | 136 if (shared_info()->never_compiled()) MarkAsFirstCompile(); |
137 } | 137 } |
138 } | 138 } |
139 | 139 |
140 | 140 |
141 CompilationInfo::CompilationInfo(const char* debug_name, Isolate* isolate, | 141 CompilationInfo::CompilationInfo(const char* debug_name, Isolate* isolate, |
142 Zone* zone, Code::Flags code_flags) | 142 Zone* zone, Code::Flags code_flags) |
143 : CompilationInfo(nullptr, debug_name, code_flags, STUB, isolate, zone) {} | 143 : CompilationInfo(nullptr, debug_name, code_flags, STUB, isolate, zone) {} |
144 | 144 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 // profiler, so they trigger their own optimization when they're called | 198 // profiler, so they trigger their own optimization when they're called |
199 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. | 199 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. |
200 bool CompilationInfo::ShouldSelfOptimize() { | 200 bool CompilationInfo::ShouldSelfOptimize() { |
201 return FLAG_crankshaft && | 201 return FLAG_crankshaft && |
202 !(literal()->flags() & AstProperties::kDontSelfOptimize) && | 202 !(literal()->flags() & AstProperties::kDontSelfOptimize) && |
203 !literal()->dont_optimize() && | 203 !literal()->dont_optimize() && |
204 literal()->scope()->AllowsLazyCompilation() && | 204 literal()->scope()->AllowsLazyCompilation() && |
205 (!has_shared_info() || !shared_info()->optimization_disabled()); | 205 (!has_shared_info() || !shared_info()->optimization_disabled()); |
206 } | 206 } |
207 | 207 |
208 | 208 void CompilationInfo::EnsureFeedbackMetadata() { |
209 void CompilationInfo::EnsureFeedbackVector() { | 209 if (feedback_metadata_.is_null()) { |
210 if (feedback_vector_.is_null()) { | 210 feedback_metadata_ = |
211 Handle<TypeFeedbackMetadata> feedback_metadata = | |
212 TypeFeedbackMetadata::New(isolate(), literal()->feedback_vector_spec()); | 211 TypeFeedbackMetadata::New(isolate(), literal()->feedback_vector_spec()); |
213 feedback_vector_ = TypeFeedbackVector::New(isolate(), feedback_metadata); | |
214 } | 212 } |
215 | 213 |
216 // It's very important that recompiles do not alter the structure of the | 214 // It's very important that recompiles do not alter the structure of the |
217 // type feedback vector. | 215 // type feedback vector. |
218 CHECK(!feedback_vector_->metadata()->SpecDiffersFrom( | 216 CHECK( |
219 literal()->feedback_vector_spec())); | 217 !feedback_metadata_->SpecDiffersFrom(literal()->feedback_vector_spec())); |
220 } | 218 } |
221 | 219 |
222 | 220 |
223 bool CompilationInfo::has_simple_parameters() { | 221 bool CompilationInfo::has_simple_parameters() { |
224 return scope()->has_simple_parameters(); | 222 return scope()->has_simple_parameters(); |
225 } | 223 } |
226 | 224 |
227 | 225 |
228 int CompilationInfo::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, | 226 int CompilationInfo::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, |
229 SourcePosition position, | 227 SourcePosition position, |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 return SetLastStatus(FAILED); | 374 return SetLastStatus(FAILED); |
377 } | 375 } |
378 if (FLAG_hydrogen_stats) { | 376 if (FLAG_hydrogen_stats) { |
379 isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed()); | 377 isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed()); |
380 } | 378 } |
381 } | 379 } |
382 | 380 |
383 DCHECK(info()->shared_info()->has_deoptimization_support()); | 381 DCHECK(info()->shared_info()->has_deoptimization_support()); |
384 DCHECK(!info()->is_first_compile()); | 382 DCHECK(!info()->is_first_compile()); |
385 | 383 |
| 384 // If we have a closure make sure it has the literals array at this point. |
| 385 if (!info()->closure().is_null()) { |
| 386 JSFunction::EnsureLiterals(info()->closure()); |
| 387 } |
| 388 |
386 bool optimization_disabled = info()->shared_info()->optimization_disabled(); | 389 bool optimization_disabled = info()->shared_info()->optimization_disabled(); |
387 bool dont_crankshaft = info()->shared_info()->dont_crankshaft(); | 390 bool dont_crankshaft = info()->shared_info()->dont_crankshaft(); |
388 | 391 |
389 // Check the enabling conditions for Turbofan. | 392 // Check the enabling conditions for Turbofan. |
390 // 1. "use asm" code. | 393 // 1. "use asm" code. |
391 bool is_turbofanable_asm = FLAG_turbo_asm && | 394 bool is_turbofanable_asm = FLAG_turbo_asm && |
392 info()->shared_info()->asm_function() && | 395 info()->shared_info()->asm_function() && |
393 !optimization_disabled; | 396 !optimization_disabled; |
394 | 397 |
395 // 2. Fallback for features unsupported by Crankshaft. | 398 // 2. Fallback for features unsupported by Crankshaft. |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( | 783 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( |
781 CompilationInfo* info) { | 784 CompilationInfo* info) { |
782 VMState<COMPILER> state(info->isolate()); | 785 VMState<COMPILER> state(info->isolate()); |
783 PostponeInterruptsScope postpone(info->isolate()); | 786 PostponeInterruptsScope postpone(info->isolate()); |
784 | 787 |
785 // Parse and update CompilationInfo with the results. | 788 // Parse and update CompilationInfo with the results. |
786 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); | 789 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); |
787 Handle<SharedFunctionInfo> shared = info->shared_info(); | 790 Handle<SharedFunctionInfo> shared = info->shared_info(); |
788 FunctionLiteral* lit = info->literal(); | 791 FunctionLiteral* lit = info->literal(); |
789 DCHECK_EQ(shared->language_mode(), lit->language_mode()); | 792 DCHECK_EQ(shared->language_mode(), lit->language_mode()); |
| 793 shared->set_num_literals(lit->materialized_literal_count()); |
790 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); | 794 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); |
791 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); | 795 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); |
792 | 796 |
793 // Compile either unoptimized code or bytecode for the interpreter. | 797 // Compile either unoptimized code or bytecode for the interpreter. |
794 if (!CompileBaselineCode(info)) return MaybeHandle<Code>(); | 798 if (!CompileBaselineCode(info)) return MaybeHandle<Code>(); |
795 if (info->code()->kind() == Code::FUNCTION) { // Only for full code. | 799 if (info->code()->kind() == Code::FUNCTION) { // Only for full code. |
796 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); | 800 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); |
797 } | 801 } |
798 | 802 |
799 // Update the shared function info with the scope info. Allocating the | 803 // Update the shared function info with the scope info. Allocating the |
800 // ScopeInfo object may cause a GC. | 804 // ScopeInfo object may cause a GC. |
801 Handle<ScopeInfo> scope_info = | 805 Handle<ScopeInfo> scope_info = |
802 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); | 806 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); |
803 shared->set_scope_info(*scope_info); | 807 shared->set_scope_info(*scope_info); |
804 | 808 |
805 // Update the code and feedback vector for the shared function info. | 809 // Update the code and feedback vector for the shared function info. |
806 shared->ReplaceCode(*info->code()); | 810 shared->ReplaceCode(*info->code()); |
807 shared->set_feedback_vector(*info->feedback_vector()); | 811 shared->set_feedback_metadata(*info->feedback_metadata()); |
808 if (info->has_bytecode_array()) { | 812 if (info->has_bytecode_array()) { |
809 DCHECK(shared->function_data()->IsUndefined()); | 813 DCHECK(shared->function_data()->IsUndefined()); |
810 shared->set_function_data(*info->bytecode_array()); | 814 shared->set_function_data(*info->bytecode_array()); |
811 } | 815 } |
812 | 816 |
813 return info->code(); | 817 return info->code(); |
814 } | 818 } |
815 | 819 |
816 | 820 |
817 MUST_USE_RESULT static MaybeHandle<Code> GetCodeFromOptimizedCodeMap( | 821 MUST_USE_RESULT static MaybeHandle<Code> GetCodeFromOptimizedCodeMap( |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 return Handle<Code>(function->shared()->code()); | 1015 return Handle<Code>(function->shared()->code()); |
1012 } | 1016 } |
1013 | 1017 |
1014 CompilationInfoWithZone info(function); | 1018 CompilationInfoWithZone info(function); |
1015 Handle<Code> result; | 1019 Handle<Code> result; |
1016 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCodeCommon(&info), | 1020 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCodeCommon(&info), |
1017 Code); | 1021 Code); |
1018 | 1022 |
1019 if (FLAG_always_opt) { | 1023 if (FLAG_always_opt) { |
1020 Handle<Code> opt_code; | 1024 Handle<Code> opt_code; |
| 1025 JSFunction::EnsureLiterals(function); |
1021 if (Compiler::GetOptimizedCode(function, Compiler::NOT_CONCURRENT) | 1026 if (Compiler::GetOptimizedCode(function, Compiler::NOT_CONCURRENT) |
1022 .ToHandle(&opt_code)) { | 1027 .ToHandle(&opt_code)) { |
1023 result = opt_code; | 1028 result = opt_code; |
1024 } | 1029 } |
1025 } | 1030 } |
1026 | 1031 |
1027 return result; | 1032 return result; |
1028 } | 1033 } |
1029 | 1034 |
1030 | 1035 |
1031 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { | 1036 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { |
1032 if (function->is_compiled()) return true; | 1037 if (function->is_compiled()) return true; |
1033 MaybeHandle<Code> maybe_code = Compiler::GetLazyCode(function); | 1038 MaybeHandle<Code> maybe_code = Compiler::GetLazyCode(function); |
1034 Handle<Code> code; | 1039 Handle<Code> code; |
| 1040 Isolate* isolate = function->GetIsolate(); |
1035 if (!maybe_code.ToHandle(&code)) { | 1041 if (!maybe_code.ToHandle(&code)) { |
1036 if (flag == CLEAR_EXCEPTION) { | 1042 if (flag == CLEAR_EXCEPTION) { |
1037 function->GetIsolate()->clear_pending_exception(); | 1043 isolate->clear_pending_exception(); |
1038 } | 1044 } |
1039 return false; | 1045 return false; |
1040 } | 1046 } |
1041 function->ReplaceCode(*code); | 1047 function->ReplaceCode(*code); |
1042 DCHECK(function->is_compiled()); | 1048 DCHECK(function->is_compiled()); |
| 1049 JSFunction::EnsureLiterals(function); |
1043 return true; | 1050 return true; |
1044 } | 1051 } |
1045 | 1052 |
1046 | 1053 |
1047 // TODO(turbofan): In the future, unoptimized code with deopt support could | 1054 // TODO(turbofan): In the future, unoptimized code with deopt support could |
1048 // be generated lazily once deopt is triggered. | 1055 // be generated lazily once deopt is triggered. |
1049 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 1056 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
1050 DCHECK_NOT_NULL(info->literal()); | 1057 DCHECK_NOT_NULL(info->literal()); |
1051 DCHECK(info->has_scope()); | 1058 DCHECK(info->has_scope()); |
1052 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1059 Handle<SharedFunctionInfo> shared = info->shared_info(); |
(...skipping 10 matching lines...) Expand all Loading... |
1063 // If the current code has reloc info for serialization, also include | 1070 // If the current code has reloc info for serialization, also include |
1064 // reloc info for serialization for the new code, so that deopt support | 1071 // reloc info for serialization for the new code, so that deopt support |
1065 // can be added without losing IC state. | 1072 // can be added without losing IC state. |
1066 if (shared->code()->kind() == Code::FUNCTION && | 1073 if (shared->code()->kind() == Code::FUNCTION && |
1067 shared->code()->has_reloc_info_for_serialization()) { | 1074 shared->code()->has_reloc_info_for_serialization()) { |
1068 unoptimized.PrepareForSerializing(); | 1075 unoptimized.PrepareForSerializing(); |
1069 } | 1076 } |
1070 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; | 1077 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; |
1071 | 1078 |
1072 shared->EnableDeoptimizationSupport(*unoptimized.code()); | 1079 shared->EnableDeoptimizationSupport(*unoptimized.code()); |
1073 shared->set_feedback_vector(*unoptimized.feedback_vector()); | 1080 shared->set_feedback_metadata(*unoptimized.feedback_metadata()); |
1074 | 1081 |
1075 info->MarkAsCompiled(); | 1082 info->MarkAsCompiled(); |
1076 | 1083 |
1077 // The scope info might not have been set if a lazily compiled | 1084 // The scope info might not have been set if a lazily compiled |
1078 // function is inlined before being called for the first time. | 1085 // function is inlined before being called for the first time. |
1079 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { | 1086 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { |
1080 Handle<ScopeInfo> target_scope_info = | 1087 Handle<ScopeInfo> target_scope_info = |
1081 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); | 1088 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); |
1082 shared->set_scope_info(*target_scope_info); | 1089 shared->set_scope_info(*target_scope_info); |
1083 } | 1090 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1139 | 1146 |
1140 static inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { | 1147 static inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { |
1141 return shared->is_toplevel() && shared->script()->IsScript() && | 1148 return shared->is_toplevel() && shared->script()->IsScript() && |
1142 Script::cast(shared->script())->compilation_type() == | 1149 Script::cast(shared->script())->compilation_type() == |
1143 Script::COMPILATION_TYPE_EVAL; | 1150 Script::COMPILATION_TYPE_EVAL; |
1144 } | 1151 } |
1145 | 1152 |
1146 | 1153 |
1147 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { | 1154 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { |
1148 Handle<SharedFunctionInfo> shared(function->shared()); | 1155 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1156 bool result; |
1149 if (IsEvalToplevel(shared)) { | 1157 if (IsEvalToplevel(shared)) { |
1150 return CompileEvalForDebugging(function, shared); | 1158 result = CompileEvalForDebugging(function, shared); |
1151 } else { | 1159 } else { |
1152 CompilationInfoWithZone info(function); | 1160 CompilationInfoWithZone info(function); |
1153 return CompileForDebugging(&info); | 1161 result = CompileForDebugging(&info); |
1154 } | 1162 } |
| 1163 JSFunction::EnsureLiterals(function); |
| 1164 return result; |
1155 } | 1165 } |
1156 | 1166 |
1157 | 1167 |
1158 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { | 1168 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { |
1159 DCHECK(shared->allows_lazy_compilation_without_context()); | 1169 DCHECK(shared->allows_lazy_compilation_without_context()); |
1160 DCHECK(!IsEvalToplevel(shared)); | 1170 DCHECK(!IsEvalToplevel(shared)); |
1161 Zone zone; | 1171 Zone zone; |
1162 ParseInfo parse_info(&zone, shared); | 1172 ParseInfo parse_info(&zone, shared); |
1163 CompilationInfo info(&parse_info); | 1173 CompilationInfo info(&parse_info); |
1164 return CompileForDebugging(&info); | 1174 return CompileForDebugging(&info); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1256 if (!CompileBaselineCode(info)) { | 1266 if (!CompileBaselineCode(info)) { |
1257 return Handle<SharedFunctionInfo>::null(); | 1267 return Handle<SharedFunctionInfo>::null(); |
1258 } | 1268 } |
1259 | 1269 |
1260 // Allocate function. | 1270 // Allocate function. |
1261 DCHECK(!info->code().is_null()); | 1271 DCHECK(!info->code().is_null()); |
1262 result = isolate->factory()->NewSharedFunctionInfo( | 1272 result = isolate->factory()->NewSharedFunctionInfo( |
1263 lit->name(), lit->materialized_literal_count(), lit->kind(), | 1273 lit->name(), lit->materialized_literal_count(), lit->kind(), |
1264 info->code(), | 1274 info->code(), |
1265 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), | 1275 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), |
1266 info->feedback_vector()); | 1276 info->feedback_metadata()); |
1267 if (info->has_bytecode_array()) { | 1277 if (info->has_bytecode_array()) { |
1268 DCHECK(result->function_data()->IsUndefined()); | 1278 DCHECK(result->function_data()->IsUndefined()); |
1269 result->set_function_data(*info->bytecode_array()); | 1279 result->set_function_data(*info->bytecode_array()); |
1270 } | 1280 } |
1271 | 1281 |
1272 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); | 1282 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); |
1273 SharedFunctionInfo::InitFromFunctionLiteral(result, lit); | 1283 SharedFunctionInfo::InitFromFunctionLiteral(result, lit); |
1274 SharedFunctionInfo::SetScript(result, script); | 1284 SharedFunctionInfo::SetScript(result, script); |
1275 result->set_is_toplevel(true); | 1285 result->set_is_toplevel(true); |
1276 if (info->is_eval()) { | 1286 if (info->is_eval()) { |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1583 !LiveEditFunctionTracker::IsActive(isolate) && | 1593 !LiveEditFunctionTracker::IsActive(isolate) && |
1584 (!info.is_debug() || allow_lazy_without_ctx); | 1594 (!info.is_debug() || allow_lazy_without_ctx); |
1585 | 1595 |
1586 bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile(); | 1596 bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile(); |
1587 | 1597 |
1588 // Generate code | 1598 // Generate code |
1589 Handle<ScopeInfo> scope_info; | 1599 Handle<ScopeInfo> scope_info; |
1590 if (lazy) { | 1600 if (lazy) { |
1591 Handle<Code> code = isolate->builtins()->CompileLazy(); | 1601 Handle<Code> code = isolate->builtins()->CompileLazy(); |
1592 info.SetCode(code); | 1602 info.SetCode(code); |
1593 // There's no need in theory for a lazy-compiled function to have a type | 1603 // There's no need in theory for a lazy-compiled function to have type |
1594 // feedback vector, but some parts of the system expect all | 1604 // feedback metadata, but some parts of the system expect all |
1595 // SharedFunctionInfo instances to have one. The size of the vector depends | 1605 // SharedFunctionInfo instances to have one. |
1596 // on how many feedback-needing nodes are in the tree, and when lazily | 1606 info.EnsureFeedbackMetadata(); |
1597 // parsing we might not know that, if this function was never parsed before. | |
1598 // In that case the vector will be replaced the next time MakeCode is | |
1599 // called. | |
1600 info.EnsureFeedbackVector(); | |
1601 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); | 1607 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); |
1602 } else if (Renumber(info.parse_info()) && GenerateBaselineCode(&info)) { | 1608 } else if (Renumber(info.parse_info()) && GenerateBaselineCode(&info)) { |
1603 // Code generation will ensure that the feedback vector is present and | 1609 // Code generation will ensure that the feedback vector is present and |
1604 // appropriately sized. | 1610 // appropriately sized. |
1605 DCHECK(!info.code().is_null()); | 1611 DCHECK(!info.code().is_null()); |
1606 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); | 1612 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
1607 if (literal->should_eager_compile() && | 1613 if (literal->should_eager_compile() && |
1608 literal->should_be_used_once_hint()) { | 1614 literal->should_be_used_once_hint()) { |
1609 info.code()->MarkToBeExecutedOnce(isolate); | 1615 info.code()->MarkToBeExecutedOnce(isolate); |
1610 } | 1616 } |
1611 } else { | 1617 } else { |
1612 return Handle<SharedFunctionInfo>::null(); | 1618 return Handle<SharedFunctionInfo>::null(); |
1613 } | 1619 } |
1614 | 1620 |
1615 if (maybe_existing.is_null()) { | 1621 if (maybe_existing.is_null()) { |
1616 // Create a shared function info object. | 1622 // Create a shared function info object. |
1617 Handle<SharedFunctionInfo> result = | 1623 Handle<SharedFunctionInfo> result = |
1618 isolate->factory()->NewSharedFunctionInfo( | 1624 isolate->factory()->NewSharedFunctionInfo( |
1619 literal->name(), literal->materialized_literal_count(), | 1625 literal->name(), literal->materialized_literal_count(), |
1620 literal->kind(), info.code(), scope_info, info.feedback_vector()); | 1626 literal->kind(), info.code(), scope_info, info.feedback_metadata()); |
1621 if (info.has_bytecode_array()) { | 1627 if (info.has_bytecode_array()) { |
1622 DCHECK(result->function_data()->IsUndefined()); | 1628 DCHECK(result->function_data()->IsUndefined()); |
1623 result->set_function_data(*info.bytecode_array()); | 1629 result->set_function_data(*info.bytecode_array()); |
1624 } | 1630 } |
1625 | 1631 |
1626 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); | 1632 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); |
1627 SharedFunctionInfo::SetScript(result, script); | 1633 SharedFunctionInfo::SetScript(result, script); |
1628 result->set_is_toplevel(false); | 1634 result->set_is_toplevel(false); |
1629 // If the outer function has been compiled before, we cannot be sure that | 1635 // If the outer function has been compiled before, we cannot be sure that |
1630 // shared function info for this function literal has been created for the | 1636 // shared function info for this function literal has been created for the |
1631 // first time. It may have already been compiled previously. | 1637 // first time. It may have already been compiled previously. |
1632 result->set_never_compiled(outer_info->is_first_compile() && lazy); | 1638 result->set_never_compiled(outer_info->is_first_compile() && lazy); |
1633 | 1639 |
1634 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); | 1640 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); |
1635 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); | 1641 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); |
1636 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); | 1642 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); |
1637 | 1643 |
1638 // Set the expected number of properties for instances and return | 1644 // Set the expected number of properties for instances and return |
1639 // the resulting function. | 1645 // the resulting function. |
1640 SetExpectedNofPropertiesFromEstimate(result, | 1646 SetExpectedNofPropertiesFromEstimate(result, |
1641 literal->expected_property_count()); | 1647 literal->expected_property_count()); |
1642 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); | 1648 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); |
1643 return result; | 1649 return result; |
1644 } else if (!lazy) { | 1650 } else if (!lazy) { |
1645 // Assert that we are not overwriting (possibly patched) debug code. | 1651 // Assert that we are not overwriting (possibly patched) debug code. |
1646 DCHECK(!existing->HasDebugCode()); | 1652 DCHECK(!existing->HasDebugCode()); |
1647 existing->ReplaceCode(*info.code()); | 1653 existing->ReplaceCode(*info.code()); |
1648 existing->set_scope_info(*scope_info); | 1654 existing->set_scope_info(*scope_info); |
1649 existing->set_feedback_vector(*info.feedback_vector()); | 1655 existing->set_feedback_metadata(*info.feedback_metadata()); |
1650 } | 1656 } |
1651 return existing; | 1657 return existing; |
1652 } | 1658 } |
1653 | 1659 |
1654 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( | 1660 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( |
1655 v8::Extension* extension, Handle<String> name) { | 1661 v8::Extension* extension, Handle<String> name) { |
1656 Isolate* isolate = name->GetIsolate(); | 1662 Isolate* isolate = name->GetIsolate(); |
1657 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); | 1663 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); |
1658 | 1664 |
1659 // Compute the function template for the native function. | 1665 // Compute the function template for the native function. |
1660 v8::Local<v8::FunctionTemplate> fun_template = | 1666 v8::Local<v8::FunctionTemplate> fun_template = |
1661 extension->GetNativeFunctionTemplate(v8_isolate, | 1667 extension->GetNativeFunctionTemplate(v8_isolate, |
1662 v8::Utils::ToLocal(name)); | 1668 v8::Utils::ToLocal(name)); |
1663 DCHECK(!fun_template.IsEmpty()); | 1669 DCHECK(!fun_template.IsEmpty()); |
1664 | 1670 |
1665 // Instantiate the function and create a shared function info from it. | 1671 // Instantiate the function and create a shared function info from it. |
1666 Handle<JSFunction> fun = Handle<JSFunction>::cast(Utils::OpenHandle( | 1672 Handle<JSFunction> fun = Handle<JSFunction>::cast(Utils::OpenHandle( |
1667 *fun_template->GetFunction(v8_isolate->GetCurrentContext()) | 1673 *fun_template->GetFunction(v8_isolate->GetCurrentContext()) |
1668 .ToLocalChecked())); | 1674 .ToLocalChecked())); |
1669 const int literals = fun->NumberOfLiterals(); | 1675 const int literals = fun->NumberOfLiterals(); |
1670 Handle<Code> code = Handle<Code>(fun->shared()->code()); | 1676 Handle<Code> code = Handle<Code>(fun->shared()->code()); |
1671 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); | 1677 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); |
1672 Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( | 1678 Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( |
1673 name, literals, FunctionKind::kNormalFunction, code, | 1679 name, literals, FunctionKind::kNormalFunction, code, |
1674 Handle<ScopeInfo>(fun->shared()->scope_info()), | 1680 Handle<ScopeInfo>(fun->shared()->scope_info()), |
1675 Handle<TypeFeedbackVector>(fun->shared()->feedback_vector())); | 1681 Handle<TypeFeedbackMetadata>(fun->shared()->feedback_metadata())); |
1676 shared->set_construct_stub(*construct_stub); | 1682 shared->set_construct_stub(*construct_stub); |
1677 | 1683 |
1678 // Copy the function data to the shared function info. | 1684 // Copy the function data to the shared function info. |
1679 shared->set_function_data(fun->shared()->function_data()); | 1685 shared->set_function_data(fun->shared()->function_data()); |
1680 int parameters = fun->shared()->internal_formal_parameter_count(); | 1686 int parameters = fun->shared()->internal_formal_parameter_count(); |
1681 shared->set_internal_formal_parameter_count(parameters); | 1687 shared->set_internal_formal_parameter_count(parameters); |
1682 | 1688 |
1683 return shared; | 1689 return shared; |
1684 } | 1690 } |
1685 | 1691 |
(...skipping 27 matching lines...) Expand all Loading... |
1713 // The function was never compiled. Compile it unoptimized first. | 1719 // The function was never compiled. Compile it unoptimized first. |
1714 // TODO(titzer): reuse the AST and scope info from this compile. | 1720 // TODO(titzer): reuse the AST and scope info from this compile. |
1715 CompilationInfoWithZone unoptimized(function); | 1721 CompilationInfoWithZone unoptimized(function); |
1716 unoptimized.EnableDeoptimizationSupport(); | 1722 unoptimized.EnableDeoptimizationSupport(); |
1717 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(¤t_code)) { | 1723 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(¤t_code)) { |
1718 return MaybeHandle<Code>(); | 1724 return MaybeHandle<Code>(); |
1719 } | 1725 } |
1720 shared->ReplaceCode(*current_code); | 1726 shared->ReplaceCode(*current_code); |
1721 } | 1727 } |
1722 | 1728 |
| 1729 // At this point we know we've compiled the function, so make sure the closure |
| 1730 // points to valid literals and type-feedback-vector. |
| 1731 JSFunction::EnsureLiterals(function); |
| 1732 |
1723 current_code->set_profiler_ticks(0); | 1733 current_code->set_profiler_ticks(0); |
1724 | 1734 |
1725 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing | 1735 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing |
1726 // an eval scope and hence would fail at parsing the eval source again. | 1736 // an eval scope and hence would fail at parsing the eval source again. |
1727 if (shared->disable_optimization_reason() == kEval) { | 1737 if (shared->disable_optimization_reason() == kEval) { |
1728 return MaybeHandle<Code>(); | 1738 return MaybeHandle<Code>(); |
1729 } | 1739 } |
1730 | 1740 |
1731 // TODO(mstarzinger): We cannot properly deserialize a scope chain for the | 1741 // TODO(mstarzinger): We cannot properly deserialize a scope chain for the |
1732 // builtin context, hence Genesis::InstallExperimentalNatives would fail. | 1742 // builtin context, hence Genesis::InstallExperimentalNatives would fail. |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1837 } | 1847 } |
1838 | 1848 |
1839 #if DEBUG | 1849 #if DEBUG |
1840 void CompilationInfo::PrintAstForTesting() { | 1850 void CompilationInfo::PrintAstForTesting() { |
1841 PrintF("--- Source from AST ---\n%s\n", | 1851 PrintF("--- Source from AST ---\n%s\n", |
1842 PrettyPrinter(isolate()).PrintProgram(literal())); | 1852 PrettyPrinter(isolate()).PrintProgram(literal())); |
1843 } | 1853 } |
1844 #endif | 1854 #endif |
1845 } // namespace internal | 1855 } // namespace internal |
1846 } // namespace v8 | 1856 } // namespace v8 |
OLD | NEW |