| 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_metadata_ = Handle<TypeFeedbackMetadata>( | 133 feedback_vector_ = Handle<TypeFeedbackVector>( |
| 134 shared_info()->feedback_metadata(), parse_info->isolate()); | 134 shared_info()->feedback_vector(), 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 void CompilationInfo::EnsureFeedbackMetadata() { | 208 |
| 209 if (feedback_metadata_.is_null()) { | 209 void CompilationInfo::EnsureFeedbackVector() { |
| 210 feedback_metadata_ = | 210 if (feedback_vector_.is_null()) { |
| 211 Handle<TypeFeedbackMetadata> feedback_metadata = |
| 211 TypeFeedbackMetadata::New(isolate(), literal()->feedback_vector_spec()); | 212 TypeFeedbackMetadata::New(isolate(), literal()->feedback_vector_spec()); |
| 213 feedback_vector_ = TypeFeedbackVector::New(isolate(), feedback_metadata); |
| 212 } | 214 } |
| 213 | 215 |
| 214 // It's very important that recompiles do not alter the structure of the | 216 // It's very important that recompiles do not alter the structure of the |
| 215 // type feedback vector. | 217 // type feedback vector. |
| 216 CHECK( | 218 CHECK(!feedback_vector_->metadata()->SpecDiffersFrom( |
| 217 !feedback_metadata_->SpecDiffersFrom(literal()->feedback_vector_spec())); | 219 literal()->feedback_vector_spec())); |
| 218 } | 220 } |
| 219 | 221 |
| 220 | 222 |
| 221 bool CompilationInfo::has_simple_parameters() { | 223 bool CompilationInfo::has_simple_parameters() { |
| 222 return scope()->has_simple_parameters(); | 224 return scope()->has_simple_parameters(); |
| 223 } | 225 } |
| 224 | 226 |
| 225 | 227 |
| 226 int CompilationInfo::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, | 228 int CompilationInfo::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, |
| 227 SourcePosition position, | 229 SourcePosition position, |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 return SetLastStatus(FAILED); | 376 return SetLastStatus(FAILED); |
| 375 } | 377 } |
| 376 if (FLAG_hydrogen_stats) { | 378 if (FLAG_hydrogen_stats) { |
| 377 isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed()); | 379 isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed()); |
| 378 } | 380 } |
| 379 } | 381 } |
| 380 | 382 |
| 381 DCHECK(info()->shared_info()->has_deoptimization_support()); | 383 DCHECK(info()->shared_info()->has_deoptimization_support()); |
| 382 DCHECK(!info()->is_first_compile()); | 384 DCHECK(!info()->is_first_compile()); |
| 383 | 385 |
| 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 | |
| 389 bool optimization_disabled = info()->shared_info()->optimization_disabled(); | 386 bool optimization_disabled = info()->shared_info()->optimization_disabled(); |
| 390 bool dont_crankshaft = info()->shared_info()->dont_crankshaft(); | 387 bool dont_crankshaft = info()->shared_info()->dont_crankshaft(); |
| 391 | 388 |
| 392 // Check the enabling conditions for Turbofan. | 389 // Check the enabling conditions for Turbofan. |
| 393 // 1. "use asm" code. | 390 // 1. "use asm" code. |
| 394 bool is_turbofanable_asm = FLAG_turbo_asm && | 391 bool is_turbofanable_asm = FLAG_turbo_asm && |
| 395 info()->shared_info()->asm_function() && | 392 info()->shared_info()->asm_function() && |
| 396 !optimization_disabled; | 393 !optimization_disabled; |
| 397 | 394 |
| 398 // 2. Fallback for features unsupported by Crankshaft. | 395 // 2. Fallback for features unsupported by Crankshaft. |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( | 805 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( |
| 809 CompilationInfo* info) { | 806 CompilationInfo* info) { |
| 810 VMState<COMPILER> state(info->isolate()); | 807 VMState<COMPILER> state(info->isolate()); |
| 811 PostponeInterruptsScope postpone(info->isolate()); | 808 PostponeInterruptsScope postpone(info->isolate()); |
| 812 | 809 |
| 813 // Parse and update CompilationInfo with the results. | 810 // Parse and update CompilationInfo with the results. |
| 814 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); | 811 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); |
| 815 Handle<SharedFunctionInfo> shared = info->shared_info(); | 812 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 816 FunctionLiteral* lit = info->literal(); | 813 FunctionLiteral* lit = info->literal(); |
| 817 DCHECK_EQ(shared->language_mode(), lit->language_mode()); | 814 DCHECK_EQ(shared->language_mode(), lit->language_mode()); |
| 818 shared->set_num_literals(lit->materialized_literal_count()); | |
| 819 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); | 815 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); |
| 820 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); | 816 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); |
| 821 | 817 |
| 822 // Compile either unoptimized code or bytecode for the interpreter. | 818 // Compile either unoptimized code or bytecode for the interpreter. |
| 823 if (!CompileBaselineCode(info)) return MaybeHandle<Code>(); | 819 if (!CompileBaselineCode(info)) return MaybeHandle<Code>(); |
| 824 if (info->code()->kind() == Code::FUNCTION) { // Only for full code. | 820 if (info->code()->kind() == Code::FUNCTION) { // Only for full code. |
| 825 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); | 821 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); |
| 826 } | 822 } |
| 827 | 823 |
| 828 // Update the shared function info with the scope info. Allocating the | 824 // Update the shared function info with the scope info. Allocating the |
| 829 // ScopeInfo object may cause a GC. | 825 // ScopeInfo object may cause a GC. |
| 830 Handle<ScopeInfo> scope_info = | 826 Handle<ScopeInfo> scope_info = |
| 831 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); | 827 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); |
| 832 shared->set_scope_info(*scope_info); | 828 shared->set_scope_info(*scope_info); |
| 833 | 829 |
| 834 // Update the code and feedback vector for the shared function info. | 830 // Update the code and feedback vector for the shared function info. |
| 835 shared->ReplaceCode(*info->code()); | 831 shared->ReplaceCode(*info->code()); |
| 836 shared->set_feedback_metadata(*info->feedback_metadata()); | 832 shared->set_feedback_vector(*info->feedback_vector()); |
| 837 if (info->has_bytecode_array()) { | 833 if (info->has_bytecode_array()) { |
| 838 DCHECK(shared->function_data()->IsUndefined()); | 834 DCHECK(shared->function_data()->IsUndefined()); |
| 839 shared->set_function_data(*info->bytecode_array()); | 835 shared->set_function_data(*info->bytecode_array()); |
| 840 } | 836 } |
| 841 | 837 |
| 842 return info->code(); | 838 return info->code(); |
| 843 } | 839 } |
| 844 | 840 |
| 845 | 841 |
| 846 MUST_USE_RESULT static MaybeHandle<Code> GetCodeFromOptimizedCodeMap( | 842 MUST_USE_RESULT static MaybeHandle<Code> GetCodeFromOptimizedCodeMap( |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1040 return Handle<Code>(function->shared()->code()); | 1036 return Handle<Code>(function->shared()->code()); |
| 1041 } | 1037 } |
| 1042 | 1038 |
| 1043 CompilationInfoWithZone info(function); | 1039 CompilationInfoWithZone info(function); |
| 1044 Handle<Code> result; | 1040 Handle<Code> result; |
| 1045 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCodeCommon(&info), | 1041 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCodeCommon(&info), |
| 1046 Code); | 1042 Code); |
| 1047 | 1043 |
| 1048 if (FLAG_always_opt) { | 1044 if (FLAG_always_opt) { |
| 1049 Handle<Code> opt_code; | 1045 Handle<Code> opt_code; |
| 1050 JSFunction::EnsureLiterals(function); | |
| 1051 if (Compiler::GetOptimizedCode(function, Compiler::NOT_CONCURRENT) | 1046 if (Compiler::GetOptimizedCode(function, Compiler::NOT_CONCURRENT) |
| 1052 .ToHandle(&opt_code)) { | 1047 .ToHandle(&opt_code)) { |
| 1053 result = opt_code; | 1048 result = opt_code; |
| 1054 } | 1049 } |
| 1055 } | 1050 } |
| 1056 | 1051 |
| 1057 return result; | 1052 return result; |
| 1058 } | 1053 } |
| 1059 | 1054 |
| 1060 | 1055 |
| 1061 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { | 1056 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { |
| 1062 if (function->is_compiled()) return true; | 1057 if (function->is_compiled()) return true; |
| 1063 MaybeHandle<Code> maybe_code = Compiler::GetLazyCode(function); | 1058 MaybeHandle<Code> maybe_code = Compiler::GetLazyCode(function); |
| 1064 Handle<Code> code; | 1059 Handle<Code> code; |
| 1065 Isolate* isolate = function->GetIsolate(); | |
| 1066 if (!maybe_code.ToHandle(&code)) { | 1060 if (!maybe_code.ToHandle(&code)) { |
| 1067 if (flag == CLEAR_EXCEPTION) { | 1061 if (flag == CLEAR_EXCEPTION) { |
| 1068 isolate->clear_pending_exception(); | 1062 function->GetIsolate()->clear_pending_exception(); |
| 1069 } | 1063 } |
| 1070 return false; | 1064 return false; |
| 1071 } | 1065 } |
| 1072 function->ReplaceCode(*code); | 1066 function->ReplaceCode(*code); |
| 1073 DCHECK(function->is_compiled()); | 1067 DCHECK(function->is_compiled()); |
| 1074 JSFunction::EnsureLiterals(function); | |
| 1075 return true; | 1068 return true; |
| 1076 } | 1069 } |
| 1077 | 1070 |
| 1078 | 1071 |
| 1079 // TODO(turbofan): In the future, unoptimized code with deopt support could | 1072 // TODO(turbofan): In the future, unoptimized code with deopt support could |
| 1080 // be generated lazily once deopt is triggered. | 1073 // be generated lazily once deopt is triggered. |
| 1081 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 1074 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
| 1082 DCHECK_NOT_NULL(info->literal()); | 1075 DCHECK_NOT_NULL(info->literal()); |
| 1083 DCHECK(info->has_scope()); | 1076 DCHECK(info->has_scope()); |
| 1084 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1077 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1095 // If the current code has reloc info for serialization, also include | 1088 // If the current code has reloc info for serialization, also include |
| 1096 // reloc info for serialization for the new code, so that deopt support | 1089 // reloc info for serialization for the new code, so that deopt support |
| 1097 // can be added without losing IC state. | 1090 // can be added without losing IC state. |
| 1098 if (shared->code()->kind() == Code::FUNCTION && | 1091 if (shared->code()->kind() == Code::FUNCTION && |
| 1099 shared->code()->has_reloc_info_for_serialization()) { | 1092 shared->code()->has_reloc_info_for_serialization()) { |
| 1100 unoptimized.PrepareForSerializing(); | 1093 unoptimized.PrepareForSerializing(); |
| 1101 } | 1094 } |
| 1102 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; | 1095 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; |
| 1103 | 1096 |
| 1104 shared->EnableDeoptimizationSupport(*unoptimized.code()); | 1097 shared->EnableDeoptimizationSupport(*unoptimized.code()); |
| 1105 shared->set_feedback_metadata(*unoptimized.feedback_metadata()); | 1098 shared->set_feedback_vector(*unoptimized.feedback_vector()); |
| 1106 | 1099 |
| 1107 info->MarkAsCompiled(); | 1100 info->MarkAsCompiled(); |
| 1108 | 1101 |
| 1109 // The scope info might not have been set if a lazily compiled | 1102 // The scope info might not have been set if a lazily compiled |
| 1110 // function is inlined before being called for the first time. | 1103 // function is inlined before being called for the first time. |
| 1111 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { | 1104 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { |
| 1112 Handle<ScopeInfo> target_scope_info = | 1105 Handle<ScopeInfo> target_scope_info = |
| 1113 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); | 1106 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); |
| 1114 shared->set_scope_info(*target_scope_info); | 1107 shared->set_scope_info(*target_scope_info); |
| 1115 } | 1108 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 | 1164 |
| 1172 static inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { | 1165 static inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { |
| 1173 return shared->is_toplevel() && shared->script()->IsScript() && | 1166 return shared->is_toplevel() && shared->script()->IsScript() && |
| 1174 Script::cast(shared->script())->compilation_type() == | 1167 Script::cast(shared->script())->compilation_type() == |
| 1175 Script::COMPILATION_TYPE_EVAL; | 1168 Script::COMPILATION_TYPE_EVAL; |
| 1176 } | 1169 } |
| 1177 | 1170 |
| 1178 | 1171 |
| 1179 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { | 1172 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { |
| 1180 Handle<SharedFunctionInfo> shared(function->shared()); | 1173 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1181 bool result; | |
| 1182 if (IsEvalToplevel(shared)) { | 1174 if (IsEvalToplevel(shared)) { |
| 1183 result = CompileEvalForDebugging(function, shared); | 1175 return CompileEvalForDebugging(function, shared); |
| 1184 } else { | 1176 } else { |
| 1185 CompilationInfoWithZone info(function); | 1177 CompilationInfoWithZone info(function); |
| 1186 result = CompileForDebugging(&info); | 1178 return CompileForDebugging(&info); |
| 1187 } | 1179 } |
| 1188 JSFunction::EnsureLiterals(function); | |
| 1189 return result; | |
| 1190 } | 1180 } |
| 1191 | 1181 |
| 1192 | 1182 |
| 1193 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { | 1183 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { |
| 1194 DCHECK(shared->allows_lazy_compilation_without_context()); | 1184 DCHECK(shared->allows_lazy_compilation_without_context()); |
| 1195 DCHECK(!IsEvalToplevel(shared)); | 1185 DCHECK(!IsEvalToplevel(shared)); |
| 1196 Zone zone; | 1186 Zone zone; |
| 1197 ParseInfo parse_info(&zone, shared); | 1187 ParseInfo parse_info(&zone, shared); |
| 1198 CompilationInfo info(&parse_info); | 1188 CompilationInfo info(&parse_info); |
| 1199 return CompileForDebugging(&info); | 1189 return CompileForDebugging(&info); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 if (!CompileBaselineCode(info)) { | 1281 if (!CompileBaselineCode(info)) { |
| 1292 return Handle<SharedFunctionInfo>::null(); | 1282 return Handle<SharedFunctionInfo>::null(); |
| 1293 } | 1283 } |
| 1294 | 1284 |
| 1295 // Allocate function. | 1285 // Allocate function. |
| 1296 DCHECK(!info->code().is_null()); | 1286 DCHECK(!info->code().is_null()); |
| 1297 result = isolate->factory()->NewSharedFunctionInfo( | 1287 result = isolate->factory()->NewSharedFunctionInfo( |
| 1298 lit->name(), lit->materialized_literal_count(), lit->kind(), | 1288 lit->name(), lit->materialized_literal_count(), lit->kind(), |
| 1299 info->code(), | 1289 info->code(), |
| 1300 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), | 1290 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), |
| 1301 info->feedback_metadata()); | 1291 info->feedback_vector()); |
| 1302 if (info->has_bytecode_array()) { | 1292 if (info->has_bytecode_array()) { |
| 1303 DCHECK(result->function_data()->IsUndefined()); | 1293 DCHECK(result->function_data()->IsUndefined()); |
| 1304 result->set_function_data(*info->bytecode_array()); | 1294 result->set_function_data(*info->bytecode_array()); |
| 1305 } | 1295 } |
| 1306 | 1296 |
| 1307 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); | 1297 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); |
| 1308 SharedFunctionInfo::InitFromFunctionLiteral(result, lit); | 1298 SharedFunctionInfo::InitFromFunctionLiteral(result, lit); |
| 1309 SharedFunctionInfo::SetScript(result, script); | 1299 SharedFunctionInfo::SetScript(result, script); |
| 1310 result->set_is_toplevel(true); | 1300 result->set_is_toplevel(true); |
| 1311 if (info->is_eval()) { | 1301 if (info->is_eval()) { |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1618 !LiveEditFunctionTracker::IsActive(isolate) && | 1608 !LiveEditFunctionTracker::IsActive(isolate) && |
| 1619 (!info.is_debug() || allow_lazy_without_ctx); | 1609 (!info.is_debug() || allow_lazy_without_ctx); |
| 1620 | 1610 |
| 1621 bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile(); | 1611 bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile(); |
| 1622 | 1612 |
| 1623 // Generate code | 1613 // Generate code |
| 1624 Handle<ScopeInfo> scope_info; | 1614 Handle<ScopeInfo> scope_info; |
| 1625 if (lazy) { | 1615 if (lazy) { |
| 1626 Handle<Code> code = isolate->builtins()->CompileLazy(); | 1616 Handle<Code> code = isolate->builtins()->CompileLazy(); |
| 1627 info.SetCode(code); | 1617 info.SetCode(code); |
| 1628 // There's no need in theory for a lazy-compiled function to have type | 1618 // There's no need in theory for a lazy-compiled function to have a type |
| 1629 // feedback metadata, but some parts of the system expect all | 1619 // feedback vector, but some parts of the system expect all |
| 1630 // SharedFunctionInfo instances to have one. | 1620 // SharedFunctionInfo instances to have one. The size of the vector depends |
| 1631 info.EnsureFeedbackMetadata(); | 1621 // on how many feedback-needing nodes are in the tree, and when lazily |
| 1622 // parsing we might not know that, if this function was never parsed before. |
| 1623 // In that case the vector will be replaced the next time MakeCode is |
| 1624 // called. |
| 1625 info.EnsureFeedbackVector(); |
| 1632 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); | 1626 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); |
| 1633 } else if (Renumber(info.parse_info()) && GenerateBaselineCode(&info)) { | 1627 } else if (Renumber(info.parse_info()) && GenerateBaselineCode(&info)) { |
| 1634 // Code generation will ensure that the feedback vector is present and | 1628 // Code generation will ensure that the feedback vector is present and |
| 1635 // appropriately sized. | 1629 // appropriately sized. |
| 1636 DCHECK(!info.code().is_null()); | 1630 DCHECK(!info.code().is_null()); |
| 1637 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); | 1631 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
| 1638 if (literal->should_eager_compile() && | 1632 if (literal->should_eager_compile() && |
| 1639 literal->should_be_used_once_hint()) { | 1633 literal->should_be_used_once_hint()) { |
| 1640 info.code()->MarkToBeExecutedOnce(isolate); | 1634 info.code()->MarkToBeExecutedOnce(isolate); |
| 1641 } | 1635 } |
| 1642 } else { | 1636 } else { |
| 1643 return Handle<SharedFunctionInfo>::null(); | 1637 return Handle<SharedFunctionInfo>::null(); |
| 1644 } | 1638 } |
| 1645 | 1639 |
| 1646 if (maybe_existing.is_null()) { | 1640 if (maybe_existing.is_null()) { |
| 1647 // Create a shared function info object. | 1641 // Create a shared function info object. |
| 1648 Handle<SharedFunctionInfo> result = | 1642 Handle<SharedFunctionInfo> result = |
| 1649 isolate->factory()->NewSharedFunctionInfo( | 1643 isolate->factory()->NewSharedFunctionInfo( |
| 1650 literal->name(), literal->materialized_literal_count(), | 1644 literal->name(), literal->materialized_literal_count(), |
| 1651 literal->kind(), info.code(), scope_info, info.feedback_metadata()); | 1645 literal->kind(), info.code(), scope_info, info.feedback_vector()); |
| 1652 if (info.has_bytecode_array()) { | 1646 if (info.has_bytecode_array()) { |
| 1653 DCHECK(result->function_data()->IsUndefined()); | 1647 DCHECK(result->function_data()->IsUndefined()); |
| 1654 result->set_function_data(*info.bytecode_array()); | 1648 result->set_function_data(*info.bytecode_array()); |
| 1655 } | 1649 } |
| 1656 | 1650 |
| 1657 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); | 1651 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); |
| 1658 SharedFunctionInfo::SetScript(result, script); | 1652 SharedFunctionInfo::SetScript(result, script); |
| 1659 result->set_is_toplevel(false); | 1653 result->set_is_toplevel(false); |
| 1660 // If the outer function has been compiled before, we cannot be sure that | 1654 // If the outer function has been compiled before, we cannot be sure that |
| 1661 // shared function info for this function literal has been created for the | 1655 // shared function info for this function literal has been created for the |
| 1662 // first time. It may have already been compiled previously. | 1656 // first time. It may have already been compiled previously. |
| 1663 result->set_never_compiled(outer_info->is_first_compile() && lazy); | 1657 result->set_never_compiled(outer_info->is_first_compile() && lazy); |
| 1664 | 1658 |
| 1665 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); | 1659 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); |
| 1666 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); | 1660 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); |
| 1667 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); | 1661 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); |
| 1668 | 1662 |
| 1669 // Set the expected number of properties for instances and return | 1663 // Set the expected number of properties for instances and return |
| 1670 // the resulting function. | 1664 // the resulting function. |
| 1671 SetExpectedNofPropertiesFromEstimate(result, | 1665 SetExpectedNofPropertiesFromEstimate(result, |
| 1672 literal->expected_property_count()); | 1666 literal->expected_property_count()); |
| 1673 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); | 1667 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); |
| 1674 return result; | 1668 return result; |
| 1675 } else if (!lazy) { | 1669 } else if (!lazy) { |
| 1676 // Assert that we are not overwriting (possibly patched) debug code. | 1670 // Assert that we are not overwriting (possibly patched) debug code. |
| 1677 DCHECK(!existing->HasDebugCode()); | 1671 DCHECK(!existing->HasDebugCode()); |
| 1678 existing->ReplaceCode(*info.code()); | 1672 existing->ReplaceCode(*info.code()); |
| 1679 existing->set_scope_info(*scope_info); | 1673 existing->set_scope_info(*scope_info); |
| 1680 existing->set_feedback_metadata(*info.feedback_metadata()); | 1674 existing->set_feedback_vector(*info.feedback_vector()); |
| 1681 } | 1675 } |
| 1682 return existing; | 1676 return existing; |
| 1683 } | 1677 } |
| 1684 | 1678 |
| 1685 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( | 1679 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( |
| 1686 v8::Extension* extension, Handle<String> name) { | 1680 v8::Extension* extension, Handle<String> name) { |
| 1687 Isolate* isolate = name->GetIsolate(); | 1681 Isolate* isolate = name->GetIsolate(); |
| 1688 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); | 1682 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); |
| 1689 | 1683 |
| 1690 // Compute the function template for the native function. | 1684 // Compute the function template for the native function. |
| 1691 v8::Local<v8::FunctionTemplate> fun_template = | 1685 v8::Local<v8::FunctionTemplate> fun_template = |
| 1692 extension->GetNativeFunctionTemplate(v8_isolate, | 1686 extension->GetNativeFunctionTemplate(v8_isolate, |
| 1693 v8::Utils::ToLocal(name)); | 1687 v8::Utils::ToLocal(name)); |
| 1694 DCHECK(!fun_template.IsEmpty()); | 1688 DCHECK(!fun_template.IsEmpty()); |
| 1695 | 1689 |
| 1696 // Instantiate the function and create a shared function info from it. | 1690 // Instantiate the function and create a shared function info from it. |
| 1697 Handle<JSFunction> fun = Handle<JSFunction>::cast(Utils::OpenHandle( | 1691 Handle<JSFunction> fun = Handle<JSFunction>::cast(Utils::OpenHandle( |
| 1698 *fun_template->GetFunction(v8_isolate->GetCurrentContext()) | 1692 *fun_template->GetFunction(v8_isolate->GetCurrentContext()) |
| 1699 .ToLocalChecked())); | 1693 .ToLocalChecked())); |
| 1700 const int literals = fun->NumberOfLiterals(); | 1694 const int literals = fun->NumberOfLiterals(); |
| 1701 Handle<Code> code = Handle<Code>(fun->shared()->code()); | 1695 Handle<Code> code = Handle<Code>(fun->shared()->code()); |
| 1702 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); | 1696 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); |
| 1703 Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( | 1697 Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( |
| 1704 name, literals, FunctionKind::kNormalFunction, code, | 1698 name, literals, FunctionKind::kNormalFunction, code, |
| 1705 Handle<ScopeInfo>(fun->shared()->scope_info()), | 1699 Handle<ScopeInfo>(fun->shared()->scope_info()), |
| 1706 Handle<TypeFeedbackMetadata>(fun->shared()->feedback_metadata())); | 1700 Handle<TypeFeedbackVector>(fun->shared()->feedback_vector())); |
| 1707 shared->set_construct_stub(*construct_stub); | 1701 shared->set_construct_stub(*construct_stub); |
| 1708 | 1702 |
| 1709 // Copy the function data to the shared function info. | 1703 // Copy the function data to the shared function info. |
| 1710 shared->set_function_data(fun->shared()->function_data()); | 1704 shared->set_function_data(fun->shared()->function_data()); |
| 1711 int parameters = fun->shared()->internal_formal_parameter_count(); | 1705 int parameters = fun->shared()->internal_formal_parameter_count(); |
| 1712 shared->set_internal_formal_parameter_count(parameters); | 1706 shared->set_internal_formal_parameter_count(parameters); |
| 1713 | 1707 |
| 1714 return shared; | 1708 return shared; |
| 1715 } | 1709 } |
| 1716 | 1710 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1744 // The function was never compiled. Compile it unoptimized first. | 1738 // The function was never compiled. Compile it unoptimized first. |
| 1745 // TODO(titzer): reuse the AST and scope info from this compile. | 1739 // TODO(titzer): reuse the AST and scope info from this compile. |
| 1746 CompilationInfoWithZone unoptimized(function); | 1740 CompilationInfoWithZone unoptimized(function); |
| 1747 unoptimized.EnableDeoptimizationSupport(); | 1741 unoptimized.EnableDeoptimizationSupport(); |
| 1748 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(¤t_code)) { | 1742 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(¤t_code)) { |
| 1749 return MaybeHandle<Code>(); | 1743 return MaybeHandle<Code>(); |
| 1750 } | 1744 } |
| 1751 shared->ReplaceCode(*current_code); | 1745 shared->ReplaceCode(*current_code); |
| 1752 } | 1746 } |
| 1753 | 1747 |
| 1754 // At this point we know we've compiled the function, so make sure the closure | |
| 1755 // points to valid literals and type-feedback-vector. | |
| 1756 JSFunction::EnsureLiterals(function); | |
| 1757 | |
| 1758 current_code->set_profiler_ticks(0); | 1748 current_code->set_profiler_ticks(0); |
| 1759 | 1749 |
| 1760 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing | 1750 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing |
| 1761 // an eval scope and hence would fail at parsing the eval source again. | 1751 // an eval scope and hence would fail at parsing the eval source again. |
| 1762 if (shared->disable_optimization_reason() == kEval) { | 1752 if (shared->disable_optimization_reason() == kEval) { |
| 1763 return MaybeHandle<Code>(); | 1753 return MaybeHandle<Code>(); |
| 1764 } | 1754 } |
| 1765 | 1755 |
| 1766 // TODO(mstarzinger): We cannot properly deserialize a scope chain for the | 1756 // TODO(mstarzinger): We cannot properly deserialize a scope chain for the |
| 1767 // builtin context, hence Genesis::InstallExperimentalNatives would fail. | 1757 // builtin context, hence Genesis::InstallExperimentalNatives would fail. |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1872 } | 1862 } |
| 1873 | 1863 |
| 1874 #if DEBUG | 1864 #if DEBUG |
| 1875 void CompilationInfo::PrintAstForTesting() { | 1865 void CompilationInfo::PrintAstForTesting() { |
| 1876 PrintF("--- Source from AST ---\n%s\n", | 1866 PrintF("--- Source from AST ---\n%s\n", |
| 1877 PrettyPrinter(isolate()).PrintProgram(literal())); | 1867 PrettyPrinter(isolate()).PrintProgram(literal())); |
| 1878 } | 1868 } |
| 1879 #endif | 1869 #endif |
| 1880 } // namespace internal | 1870 } // namespace internal |
| 1881 } // namespace v8 | 1871 } // namespace v8 |
| OLD | NEW |