| 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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing(); | 133 if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing(); |
| 134 if (FLAG_turbo_inlining) MarkAsInliningEnabled(); | 134 if (FLAG_turbo_inlining) MarkAsInliningEnabled(); |
| 135 if (FLAG_turbo_source_positions) MarkAsSourcePositionsEnabled(); | 135 if (FLAG_turbo_source_positions) MarkAsSourcePositionsEnabled(); |
| 136 if (FLAG_turbo_splitting) MarkAsSplittingEnabled(); | 136 if (FLAG_turbo_splitting) MarkAsSplittingEnabled(); |
| 137 if (FLAG_turbo_types) MarkAsTypingEnabled(); | 137 if (FLAG_turbo_types) MarkAsTypingEnabled(); |
| 138 | 138 |
| 139 if (has_shared_info()) { | 139 if (has_shared_info()) { |
| 140 if (shared_info()->is_compiled()) { | 140 if (shared_info()->is_compiled()) { |
| 141 // We should initialize the CompilationInfo feedback vector from the | 141 // We should initialize the CompilationInfo feedback vector from the |
| 142 // passed in shared info, rather than creating a new one. | 142 // passed in shared info, rather than creating a new one. |
| 143 feedback_vector_ = Handle<TypeFeedbackVector>( | 143 feedback_metadata_ = Handle<TypeFeedbackMetadata>( |
| 144 shared_info()->feedback_vector(), parse_info->isolate()); | 144 shared_info()->feedback_metadata(), parse_info->isolate()); |
| 145 } | 145 } |
| 146 if (shared_info()->never_compiled()) MarkAsFirstCompile(); | 146 if (shared_info()->never_compiled()) MarkAsFirstCompile(); |
| 147 } | 147 } |
| 148 } | 148 } |
| 149 | 149 |
| 150 | 150 |
| 151 CompilationInfo::CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone) | 151 CompilationInfo::CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone) |
| 152 : CompilationInfo(nullptr, stub, CodeStub::MajorName(stub->MajorKey()), | 152 : CompilationInfo(nullptr, stub, CodeStub::MajorName(stub->MajorKey()), |
| 153 STUB, isolate, zone) {} | 153 STUB, isolate, zone) {} |
| 154 | 154 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. | 227 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. |
| 228 bool CompilationInfo::ShouldSelfOptimize() { | 228 bool CompilationInfo::ShouldSelfOptimize() { |
| 229 return FLAG_crankshaft && | 229 return FLAG_crankshaft && |
| 230 !(literal()->flags() & AstProperties::kDontSelfOptimize) && | 230 !(literal()->flags() & AstProperties::kDontSelfOptimize) && |
| 231 !literal()->dont_optimize() && | 231 !literal()->dont_optimize() && |
| 232 literal()->scope()->AllowsLazyCompilation() && | 232 literal()->scope()->AllowsLazyCompilation() && |
| 233 (!has_shared_info() || !shared_info()->optimization_disabled()); | 233 (!has_shared_info() || !shared_info()->optimization_disabled()); |
| 234 } | 234 } |
| 235 | 235 |
| 236 | 236 |
| 237 void CompilationInfo::EnsureFeedbackVector() { | 237 void CompilationInfo::EnsureFeedbackMetadata() { |
| 238 if (feedback_vector_.is_null()) { | 238 if (feedback_metadata_.is_null()) { |
| 239 Handle<TypeFeedbackMetadata> feedback_metadata = | 239 feedback_metadata_ = |
| 240 TypeFeedbackMetadata::New(isolate(), literal()->feedback_vector_spec()); | 240 TypeFeedbackMetadata::New(isolate(), literal()->feedback_vector_spec()); |
| 241 feedback_vector_ = TypeFeedbackVector::New(isolate(), feedback_metadata); | |
| 242 } | 241 } |
| 243 | 242 |
| 244 // It's very important that recompiles do not alter the structure of the | 243 // It's very important that recompiles do not alter the structure of the |
| 245 // type feedback vector. | 244 // type feedback vector. |
| 246 CHECK(!feedback_vector_->metadata()->SpecDiffersFrom( | 245 CHECK( |
| 247 literal()->feedback_vector_spec())); | 246 !feedback_metadata_->SpecDiffersFrom(literal()->feedback_vector_spec())); |
| 248 } | 247 } |
| 249 | 248 |
| 250 | 249 |
| 251 bool CompilationInfo::has_simple_parameters() { | 250 bool CompilationInfo::has_simple_parameters() { |
| 252 return scope()->has_simple_parameters(); | 251 return scope()->has_simple_parameters(); |
| 253 } | 252 } |
| 254 | 253 |
| 255 | 254 |
| 256 int CompilationInfo::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, | 255 int CompilationInfo::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, |
| 257 SourcePosition position, | 256 SourcePosition position, |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 return SetLastStatus(FAILED); | 403 return SetLastStatus(FAILED); |
| 405 } | 404 } |
| 406 if (FLAG_hydrogen_stats) { | 405 if (FLAG_hydrogen_stats) { |
| 407 isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed()); | 406 isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed()); |
| 408 } | 407 } |
| 409 } | 408 } |
| 410 | 409 |
| 411 DCHECK(info()->shared_info()->has_deoptimization_support()); | 410 DCHECK(info()->shared_info()->has_deoptimization_support()); |
| 412 DCHECK(!info()->is_first_compile()); | 411 DCHECK(!info()->is_first_compile()); |
| 413 | 412 |
| 413 // If we have a closure make sure it has the literals array at this point. |
| 414 if (!info()->closure().is_null()) { |
| 415 JSFunction::EnsureLiterals(info()->closure()); |
| 416 } |
| 417 |
| 414 bool optimization_disabled = info()->shared_info()->optimization_disabled(); | 418 bool optimization_disabled = info()->shared_info()->optimization_disabled(); |
| 415 bool dont_crankshaft = info()->shared_info()->dont_crankshaft(); | 419 bool dont_crankshaft = info()->shared_info()->dont_crankshaft(); |
| 416 | 420 |
| 417 // Check the enabling conditions for Turbofan. | 421 // Check the enabling conditions for Turbofan. |
| 418 // 1. "use asm" code. | 422 // 1. "use asm" code. |
| 419 bool is_turbofanable_asm = FLAG_turbo_asm && | 423 bool is_turbofanable_asm = FLAG_turbo_asm && |
| 420 info()->shared_info()->asm_function() && | 424 info()->shared_info()->asm_function() && |
| 421 !optimization_disabled; | 425 !optimization_disabled; |
| 422 | 426 |
| 423 // 2. Fallback for features unsupported by Crankshaft. | 427 // 2. Fallback for features unsupported by Crankshaft. |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( | 832 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( |
| 829 CompilationInfo* info) { | 833 CompilationInfo* info) { |
| 830 VMState<COMPILER> state(info->isolate()); | 834 VMState<COMPILER> state(info->isolate()); |
| 831 PostponeInterruptsScope postpone(info->isolate()); | 835 PostponeInterruptsScope postpone(info->isolate()); |
| 832 | 836 |
| 833 // Parse and update CompilationInfo with the results. | 837 // Parse and update CompilationInfo with the results. |
| 834 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); | 838 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); |
| 835 Handle<SharedFunctionInfo> shared = info->shared_info(); | 839 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 836 FunctionLiteral* lit = info->literal(); | 840 FunctionLiteral* lit = info->literal(); |
| 837 DCHECK_EQ(shared->language_mode(), lit->language_mode()); | 841 DCHECK_EQ(shared->language_mode(), lit->language_mode()); |
| 842 shared->set_num_literals(lit->materialized_literal_count()); |
| 838 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); | 843 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); |
| 839 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); | 844 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); |
| 840 | 845 |
| 841 // Compile either unoptimized code or bytecode for the interpreter. | 846 // Compile either unoptimized code or bytecode for the interpreter. |
| 842 if (!CompileBaselineCode(info)) return MaybeHandle<Code>(); | 847 if (!CompileBaselineCode(info)) return MaybeHandle<Code>(); |
| 843 if (info->code()->kind() == Code::FUNCTION) { // Only for full code. | 848 if (info->code()->kind() == Code::FUNCTION) { // Only for full code. |
| 844 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); | 849 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); |
| 845 } | 850 } |
| 846 | 851 |
| 847 // Update the shared function info with the scope info. Allocating the | 852 // Update the shared function info with the scope info. Allocating the |
| 848 // ScopeInfo object may cause a GC. | 853 // ScopeInfo object may cause a GC. |
| 849 Handle<ScopeInfo> scope_info = | 854 Handle<ScopeInfo> scope_info = |
| 850 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); | 855 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); |
| 851 shared->set_scope_info(*scope_info); | 856 shared->set_scope_info(*scope_info); |
| 852 | 857 |
| 853 // Update the code and feedback vector for the shared function info. | 858 // Update the code and feedback vector for the shared function info. |
| 854 shared->ReplaceCode(*info->code()); | 859 shared->ReplaceCode(*info->code()); |
| 855 shared->set_feedback_vector(*info->feedback_vector()); | 860 shared->set_feedback_metadata(*info->feedback_metadata()); |
| 856 if (info->has_bytecode_array()) { | 861 if (info->has_bytecode_array()) { |
| 857 DCHECK(shared->function_data()->IsUndefined()); | 862 DCHECK(shared->function_data()->IsUndefined()); |
| 858 shared->set_function_data(*info->bytecode_array()); | 863 shared->set_function_data(*info->bytecode_array()); |
| 859 } | 864 } |
| 860 | 865 |
| 861 return info->code(); | 866 return info->code(); |
| 862 } | 867 } |
| 863 | 868 |
| 864 | 869 |
| 865 MUST_USE_RESULT static MaybeHandle<Code> GetCodeFromOptimizedCodeMap( | 870 MUST_USE_RESULT static MaybeHandle<Code> GetCodeFromOptimizedCodeMap( |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 return Handle<Code>(function->shared()->code()); | 1064 return Handle<Code>(function->shared()->code()); |
| 1060 } | 1065 } |
| 1061 | 1066 |
| 1062 CompilationInfoWithZone info(function); | 1067 CompilationInfoWithZone info(function); |
| 1063 Handle<Code> result; | 1068 Handle<Code> result; |
| 1064 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCodeCommon(&info), | 1069 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCodeCommon(&info), |
| 1065 Code); | 1070 Code); |
| 1066 | 1071 |
| 1067 if (FLAG_always_opt) { | 1072 if (FLAG_always_opt) { |
| 1068 Handle<Code> opt_code; | 1073 Handle<Code> opt_code; |
| 1074 JSFunction::EnsureLiterals(function); |
| 1069 if (Compiler::GetOptimizedCode( | 1075 if (Compiler::GetOptimizedCode( |
| 1070 function, result, | 1076 function, result, |
| 1071 Compiler::NOT_CONCURRENT).ToHandle(&opt_code)) { | 1077 Compiler::NOT_CONCURRENT).ToHandle(&opt_code)) { |
| 1072 result = opt_code; | 1078 result = opt_code; |
| 1073 } | 1079 } |
| 1074 } | 1080 } |
| 1075 | 1081 |
| 1076 return result; | 1082 return result; |
| 1077 } | 1083 } |
| 1078 | 1084 |
| 1079 | 1085 |
| 1080 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { | 1086 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { |
| 1081 if (function->is_compiled()) return true; | 1087 if (function->is_compiled()) return true; |
| 1082 MaybeHandle<Code> maybe_code = Compiler::GetLazyCode(function); | 1088 MaybeHandle<Code> maybe_code = Compiler::GetLazyCode(function); |
| 1083 Handle<Code> code; | 1089 Handle<Code> code; |
| 1090 Isolate* isolate = function->GetIsolate(); |
| 1084 if (!maybe_code.ToHandle(&code)) { | 1091 if (!maybe_code.ToHandle(&code)) { |
| 1085 if (flag == CLEAR_EXCEPTION) { | 1092 if (flag == CLEAR_EXCEPTION) { |
| 1086 function->GetIsolate()->clear_pending_exception(); | 1093 isolate->clear_pending_exception(); |
| 1087 } | 1094 } |
| 1088 return false; | 1095 return false; |
| 1089 } | 1096 } |
| 1090 function->ReplaceCode(*code); | 1097 function->ReplaceCode(*code); |
| 1091 DCHECK(function->is_compiled()); | 1098 DCHECK(function->is_compiled()); |
| 1099 JSFunction::EnsureLiterals(function); |
| 1092 return true; | 1100 return true; |
| 1093 } | 1101 } |
| 1094 | 1102 |
| 1095 | 1103 |
| 1096 // TODO(turbofan): In the future, unoptimized code with deopt support could | 1104 // TODO(turbofan): In the future, unoptimized code with deopt support could |
| 1097 // be generated lazily once deopt is triggered. | 1105 // be generated lazily once deopt is triggered. |
| 1098 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 1106 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
| 1099 DCHECK_NOT_NULL(info->literal()); | 1107 DCHECK_NOT_NULL(info->literal()); |
| 1100 DCHECK(info->has_scope()); | 1108 DCHECK(info->has_scope()); |
| 1101 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1109 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1112 // If the current code has reloc info for serialization, also include | 1120 // If the current code has reloc info for serialization, also include |
| 1113 // reloc info for serialization for the new code, so that deopt support | 1121 // reloc info for serialization for the new code, so that deopt support |
| 1114 // can be added without losing IC state. | 1122 // can be added without losing IC state. |
| 1115 if (shared->code()->kind() == Code::FUNCTION && | 1123 if (shared->code()->kind() == Code::FUNCTION && |
| 1116 shared->code()->has_reloc_info_for_serialization()) { | 1124 shared->code()->has_reloc_info_for_serialization()) { |
| 1117 unoptimized.PrepareForSerializing(); | 1125 unoptimized.PrepareForSerializing(); |
| 1118 } | 1126 } |
| 1119 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; | 1127 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; |
| 1120 | 1128 |
| 1121 shared->EnableDeoptimizationSupport(*unoptimized.code()); | 1129 shared->EnableDeoptimizationSupport(*unoptimized.code()); |
| 1122 shared->set_feedback_vector(*unoptimized.feedback_vector()); | 1130 shared->set_feedback_metadata(*unoptimized.feedback_metadata()); |
| 1123 | 1131 |
| 1124 info->MarkAsCompiled(); | 1132 info->MarkAsCompiled(); |
| 1125 | 1133 |
| 1126 // The scope info might not have been set if a lazily compiled | 1134 // The scope info might not have been set if a lazily compiled |
| 1127 // function is inlined before being called for the first time. | 1135 // function is inlined before being called for the first time. |
| 1128 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { | 1136 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { |
| 1129 Handle<ScopeInfo> target_scope_info = | 1137 Handle<ScopeInfo> target_scope_info = |
| 1130 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); | 1138 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); |
| 1131 shared->set_scope_info(*target_scope_info); | 1139 shared->set_scope_info(*target_scope_info); |
| 1132 } | 1140 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 | 1196 |
| 1189 static inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { | 1197 static inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { |
| 1190 return shared->is_toplevel() && shared->script()->IsScript() && | 1198 return shared->is_toplevel() && shared->script()->IsScript() && |
| 1191 Script::cast(shared->script())->compilation_type() == | 1199 Script::cast(shared->script())->compilation_type() == |
| 1192 Script::COMPILATION_TYPE_EVAL; | 1200 Script::COMPILATION_TYPE_EVAL; |
| 1193 } | 1201 } |
| 1194 | 1202 |
| 1195 | 1203 |
| 1196 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { | 1204 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { |
| 1197 Handle<SharedFunctionInfo> shared(function->shared()); | 1205 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1206 bool result; |
| 1198 if (IsEvalToplevel(shared)) { | 1207 if (IsEvalToplevel(shared)) { |
| 1199 return CompileEvalForDebugging(function, shared); | 1208 result = CompileEvalForDebugging(function, shared); |
| 1200 } else { | 1209 } else { |
| 1201 CompilationInfoWithZone info(function); | 1210 CompilationInfoWithZone info(function); |
| 1202 return CompileForDebugging(&info); | 1211 result = CompileForDebugging(&info); |
| 1203 } | 1212 } |
| 1213 JSFunction::EnsureLiterals(function); |
| 1214 return result; |
| 1204 } | 1215 } |
| 1205 | 1216 |
| 1206 | 1217 |
| 1207 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { | 1218 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { |
| 1208 DCHECK(shared->allows_lazy_compilation_without_context()); | 1219 DCHECK(shared->allows_lazy_compilation_without_context()); |
| 1209 DCHECK(!IsEvalToplevel(shared)); | 1220 DCHECK(!IsEvalToplevel(shared)); |
| 1210 Zone zone; | 1221 Zone zone; |
| 1211 ParseInfo parse_info(&zone, shared); | 1222 ParseInfo parse_info(&zone, shared); |
| 1212 CompilationInfo info(&parse_info); | 1223 CompilationInfo info(&parse_info); |
| 1213 return CompileForDebugging(&info); | 1224 return CompileForDebugging(&info); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 if (!CompileBaselineCode(info)) { | 1316 if (!CompileBaselineCode(info)) { |
| 1306 return Handle<SharedFunctionInfo>::null(); | 1317 return Handle<SharedFunctionInfo>::null(); |
| 1307 } | 1318 } |
| 1308 | 1319 |
| 1309 // Allocate function. | 1320 // Allocate function. |
| 1310 DCHECK(!info->code().is_null()); | 1321 DCHECK(!info->code().is_null()); |
| 1311 result = isolate->factory()->NewSharedFunctionInfo( | 1322 result = isolate->factory()->NewSharedFunctionInfo( |
| 1312 lit->name(), lit->materialized_literal_count(), lit->kind(), | 1323 lit->name(), lit->materialized_literal_count(), lit->kind(), |
| 1313 info->code(), | 1324 info->code(), |
| 1314 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), | 1325 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), |
| 1315 info->feedback_vector()); | 1326 info->feedback_metadata()); |
| 1316 if (info->has_bytecode_array()) { | 1327 if (info->has_bytecode_array()) { |
| 1317 DCHECK(result->function_data()->IsUndefined()); | 1328 DCHECK(result->function_data()->IsUndefined()); |
| 1318 result->set_function_data(*info->bytecode_array()); | 1329 result->set_function_data(*info->bytecode_array()); |
| 1319 } | 1330 } |
| 1320 | 1331 |
| 1321 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); | 1332 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); |
| 1322 SharedFunctionInfo::InitFromFunctionLiteral(result, lit); | 1333 SharedFunctionInfo::InitFromFunctionLiteral(result, lit); |
| 1323 SharedFunctionInfo::SetScript(result, script); | 1334 SharedFunctionInfo::SetScript(result, script); |
| 1324 result->set_is_toplevel(true); | 1335 result->set_is_toplevel(true); |
| 1325 if (info->is_eval()) { | 1336 if (info->is_eval()) { |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1632 !LiveEditFunctionTracker::IsActive(isolate) && | 1643 !LiveEditFunctionTracker::IsActive(isolate) && |
| 1633 (!info.is_debug() || allow_lazy_without_ctx); | 1644 (!info.is_debug() || allow_lazy_without_ctx); |
| 1634 | 1645 |
| 1635 bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile(); | 1646 bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile(); |
| 1636 | 1647 |
| 1637 // Generate code | 1648 // Generate code |
| 1638 Handle<ScopeInfo> scope_info; | 1649 Handle<ScopeInfo> scope_info; |
| 1639 if (lazy) { | 1650 if (lazy) { |
| 1640 Handle<Code> code = isolate->builtins()->CompileLazy(); | 1651 Handle<Code> code = isolate->builtins()->CompileLazy(); |
| 1641 info.SetCode(code); | 1652 info.SetCode(code); |
| 1642 // There's no need in theory for a lazy-compiled function to have a type | 1653 // There's no need in theory for a lazy-compiled function to have type |
| 1643 // feedback vector, but some parts of the system expect all | 1654 // feedback metadata, but some parts of the system expect all |
| 1644 // SharedFunctionInfo instances to have one. The size of the vector depends | 1655 // SharedFunctionInfo instances to have one. |
| 1645 // on how many feedback-needing nodes are in the tree, and when lazily | 1656 info.EnsureFeedbackMetadata(); |
| 1646 // parsing we might not know that, if this function was never parsed before. | |
| 1647 // In that case the vector will be replaced the next time MakeCode is | |
| 1648 // called. | |
| 1649 info.EnsureFeedbackVector(); | |
| 1650 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); | 1657 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); |
| 1651 } else if (Renumber(info.parse_info()) && GenerateBaselineCode(&info)) { | 1658 } else if (Renumber(info.parse_info()) && GenerateBaselineCode(&info)) { |
| 1652 // Code generation will ensure that the feedback vector is present and | 1659 // Code generation will ensure that the feedback vector is present and |
| 1653 // appropriately sized. | 1660 // appropriately sized. |
| 1654 DCHECK(!info.code().is_null()); | 1661 DCHECK(!info.code().is_null()); |
| 1655 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); | 1662 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
| 1656 if (literal->should_eager_compile() && | 1663 if (literal->should_eager_compile() && |
| 1657 literal->should_be_used_once_hint()) { | 1664 literal->should_be_used_once_hint()) { |
| 1658 info.code()->MarkToBeExecutedOnce(isolate); | 1665 info.code()->MarkToBeExecutedOnce(isolate); |
| 1659 } | 1666 } |
| 1660 } else { | 1667 } else { |
| 1661 return Handle<SharedFunctionInfo>::null(); | 1668 return Handle<SharedFunctionInfo>::null(); |
| 1662 } | 1669 } |
| 1663 | 1670 |
| 1664 if (maybe_existing.is_null()) { | 1671 if (maybe_existing.is_null()) { |
| 1665 // Create a shared function info object. | 1672 // Create a shared function info object. |
| 1666 Handle<SharedFunctionInfo> result = | 1673 Handle<SharedFunctionInfo> result = |
| 1667 isolate->factory()->NewSharedFunctionInfo( | 1674 isolate->factory()->NewSharedFunctionInfo( |
| 1668 literal->name(), literal->materialized_literal_count(), | 1675 literal->name(), literal->materialized_literal_count(), |
| 1669 literal->kind(), info.code(), scope_info, info.feedback_vector()); | 1676 literal->kind(), info.code(), scope_info, info.feedback_metadata()); |
| 1670 if (info.has_bytecode_array()) { | 1677 if (info.has_bytecode_array()) { |
| 1671 DCHECK(result->function_data()->IsUndefined()); | 1678 DCHECK(result->function_data()->IsUndefined()); |
| 1672 result->set_function_data(*info.bytecode_array()); | 1679 result->set_function_data(*info.bytecode_array()); |
| 1673 } | 1680 } |
| 1674 | 1681 |
| 1675 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); | 1682 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); |
| 1676 SharedFunctionInfo::SetScript(result, script); | 1683 SharedFunctionInfo::SetScript(result, script); |
| 1677 result->set_is_toplevel(false); | 1684 result->set_is_toplevel(false); |
| 1678 // If the outer function has been compiled before, we cannot be sure that | 1685 // If the outer function has been compiled before, we cannot be sure that |
| 1679 // shared function info for this function literal has been created for the | 1686 // shared function info for this function literal has been created for the |
| 1680 // first time. It may have already been compiled previously. | 1687 // first time. It may have already been compiled previously. |
| 1681 result->set_never_compiled(outer_info->is_first_compile() && lazy); | 1688 result->set_never_compiled(outer_info->is_first_compile() && lazy); |
| 1682 | 1689 |
| 1683 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); | 1690 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); |
| 1684 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); | 1691 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); |
| 1685 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); | 1692 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); |
| 1686 | 1693 |
| 1687 // Set the expected number of properties for instances and return | 1694 // Set the expected number of properties for instances and return |
| 1688 // the resulting function. | 1695 // the resulting function. |
| 1689 SetExpectedNofPropertiesFromEstimate(result, | 1696 SetExpectedNofPropertiesFromEstimate(result, |
| 1690 literal->expected_property_count()); | 1697 literal->expected_property_count()); |
| 1691 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); | 1698 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); |
| 1692 return result; | 1699 return result; |
| 1693 } else if (!lazy) { | 1700 } else if (!lazy) { |
| 1694 // Assert that we are not overwriting (possibly patched) debug code. | 1701 // Assert that we are not overwriting (possibly patched) debug code. |
| 1695 DCHECK(!existing->HasDebugCode()); | 1702 DCHECK(!existing->HasDebugCode()); |
| 1696 existing->ReplaceCode(*info.code()); | 1703 existing->ReplaceCode(*info.code()); |
| 1697 existing->set_scope_info(*scope_info); | 1704 existing->set_scope_info(*scope_info); |
| 1698 existing->set_feedback_vector(*info.feedback_vector()); | 1705 existing->set_feedback_metadata(*info.feedback_metadata()); |
| 1699 } | 1706 } |
| 1700 return existing; | 1707 return existing; |
| 1701 } | 1708 } |
| 1702 | 1709 |
| 1703 | 1710 |
| 1704 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function, | 1711 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function, |
| 1705 Handle<Code> current_code, | 1712 Handle<Code> current_code, |
| 1706 ConcurrencyMode mode, | 1713 ConcurrencyMode mode, |
| 1707 BailoutId osr_ast_id, | 1714 BailoutId osr_ast_id, |
| 1708 JavaScriptFrame* osr_frame) { | 1715 JavaScriptFrame* osr_frame) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1731 // The function was never compiled. Compile it unoptimized first. | 1738 // The function was never compiled. Compile it unoptimized first. |
| 1732 // TODO(titzer): reuse the AST and scope info from this compile. | 1739 // TODO(titzer): reuse the AST and scope info from this compile. |
| 1733 CompilationInfoWithZone unoptimized(function); | 1740 CompilationInfoWithZone unoptimized(function); |
| 1734 unoptimized.EnableDeoptimizationSupport(); | 1741 unoptimized.EnableDeoptimizationSupport(); |
| 1735 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(¤t_code)) { | 1742 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(¤t_code)) { |
| 1736 return MaybeHandle<Code>(); | 1743 return MaybeHandle<Code>(); |
| 1737 } | 1744 } |
| 1738 shared->ReplaceCode(*current_code); | 1745 shared->ReplaceCode(*current_code); |
| 1739 } | 1746 } |
| 1740 | 1747 |
| 1748 // At this point we know we've compiled the function, so make sure the closure |
| 1749 // points to valid literals and type-feedback-vector. |
| 1750 JSFunction::EnsureLiterals(function); |
| 1751 |
| 1741 current_code->set_profiler_ticks(0); | 1752 current_code->set_profiler_ticks(0); |
| 1742 | 1753 |
| 1743 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing | 1754 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing |
| 1744 // an eval scope and hence would fail at parsing the eval source again. | 1755 // an eval scope and hence would fail at parsing the eval source again. |
| 1745 if (shared->disable_optimization_reason() == kEval) { | 1756 if (shared->disable_optimization_reason() == kEval) { |
| 1746 return MaybeHandle<Code>(); | 1757 return MaybeHandle<Code>(); |
| 1747 } | 1758 } |
| 1748 | 1759 |
| 1749 // TODO(mstarzinger): We cannot properly deserialize a scope chain for the | 1760 // TODO(mstarzinger): We cannot properly deserialize a scope chain for the |
| 1750 // builtin context, hence Genesis::InstallExperimentalNatives would fail. | 1761 // builtin context, hence Genesis::InstallExperimentalNatives would fail. |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1855 } | 1866 } |
| 1856 | 1867 |
| 1857 #if DEBUG | 1868 #if DEBUG |
| 1858 void CompilationInfo::PrintAstForTesting() { | 1869 void CompilationInfo::PrintAstForTesting() { |
| 1859 PrintF("--- Source from AST ---\n%s\n", | 1870 PrintF("--- Source from AST ---\n%s\n", |
| 1860 PrettyPrinter(isolate()).PrintProgram(literal())); | 1871 PrettyPrinter(isolate()).PrintProgram(literal())); |
| 1861 } | 1872 } |
| 1862 #endif | 1873 #endif |
| 1863 } // namespace internal | 1874 } // namespace internal |
| 1864 } // namespace v8 | 1875 } // namespace v8 |
| OLD | NEW |