| 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 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "src/asmjs/asm-js.h" | 10 #include "src/asmjs/asm-js.h" |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 } | 298 } |
| 299 | 299 |
| 300 // It's very important that recompiles do not alter the structure of the type | 300 // It's very important that recompiles do not alter the structure of the type |
| 301 // feedback vector. Verify that the structure fits the function literal. | 301 // feedback vector. Verify that the structure fits the function literal. |
| 302 CHECK(!info->shared_info()->feedback_metadata()->SpecDiffersFrom( | 302 CHECK(!info->shared_info()->feedback_metadata()->SpecDiffersFrom( |
| 303 info->literal()->feedback_vector_spec())); | 303 info->literal()->feedback_vector_spec())); |
| 304 } | 304 } |
| 305 | 305 |
| 306 bool UseTurboFan(Handle<SharedFunctionInfo> shared) { | 306 bool UseTurboFan(Handle<SharedFunctionInfo> shared) { |
| 307 bool optimization_disabled = shared->optimization_disabled(); | 307 bool optimization_disabled = shared->optimization_disabled(); |
| 308 bool dont_crankshaft = shared->dont_crankshaft(); | 308 bool must_use_ignition_turbo = shared->must_use_ignition_turbo(); |
| 309 | 309 |
| 310 // Check the enabling conditions for Turbofan. | 310 // Check the enabling conditions for Turbofan. |
| 311 // 1. "use asm" code. | 311 // 1. "use asm" code. |
| 312 bool is_turbofanable_asm = | 312 bool is_turbofanable_asm = |
| 313 FLAG_turbo_asm && shared->asm_function() && !optimization_disabled; | 313 FLAG_turbo_asm && shared->asm_function() && !optimization_disabled; |
| 314 | 314 |
| 315 // 2. Fallback for features unsupported by Crankshaft. | 315 // 2. Fallback for features unsupported by Crankshaft. |
| 316 bool is_unsupported_by_crankshaft_but_turbofanable = | 316 bool is_unsupported_by_crankshaft_but_turbofanable = |
| 317 dont_crankshaft && strcmp(FLAG_turbo_filter, "~~") == 0 && | 317 must_use_ignition_turbo && strcmp(FLAG_turbo_filter, "~~") == 0 && |
| 318 !optimization_disabled; | 318 !optimization_disabled; |
| 319 | 319 |
| 320 // 3. Explicitly enabled by the command-line filter. | 320 // 3. Explicitly enabled by the command-line filter. |
| 321 bool passes_turbo_filter = shared->PassesFilter(FLAG_turbo_filter); | 321 bool passes_turbo_filter = shared->PassesFilter(FLAG_turbo_filter); |
| 322 | 322 |
| 323 return is_turbofanable_asm || is_unsupported_by_crankshaft_but_turbofanable || | 323 return is_turbofanable_asm || is_unsupported_by_crankshaft_but_turbofanable || |
| 324 passes_turbo_filter; | 324 passes_turbo_filter; |
| 325 } | 325 } |
| 326 | 326 |
| 327 bool ShouldUseIgnition(CompilationInfo* info) { | 327 bool ShouldUseIgnition(CompilationInfo* info) { |
| 328 DCHECK(info->has_shared_info()); | 328 DCHECK(info->has_shared_info()); |
| 329 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 330 |
| 331 // Code which can't be supported by the old pipeline should use Ignition. |
| 332 if (shared->must_use_ignition_turbo()) return true; |
| 329 | 333 |
| 330 // Resumable functions are not supported by {FullCodeGenerator}, suspended | 334 // Resumable functions are not supported by {FullCodeGenerator}, suspended |
| 331 // activations stored as {JSGeneratorObject} on the heap always assume the | 335 // activations stored as {JSGeneratorObject} on the heap always assume the |
| 332 // underlying code to be based on the bytecode array. | 336 // underlying code to be based on the bytecode array. |
| 333 // TODO(mstarzinger): Once we want to deprecate even more support from the | 337 DCHECK(!IsResumableFunction(shared->kind())); |
| 334 // {FullCodeGenerator}, we will compute an appropriate bit in {AstNumbering} | |
| 335 // and turn this predicate into a DCHECK instead. | |
| 336 if (IsResumableFunction(info->shared_info()->kind())) { | |
| 337 return true; | |
| 338 } | |
| 339 | 338 |
| 340 // Skip Ignition for asm.js functions. | 339 // Skip Ignition for asm.js functions. |
| 341 if (info->shared_info()->asm_function()) { | 340 if (shared->asm_function()) return false; |
| 341 |
| 342 // Skip Ignition for asm wasm code. |
| 343 if (FLAG_validate_asm && shared->HasAsmWasmData()) { |
| 342 return false; | 344 return false; |
| 343 } | 345 } |
| 344 | 346 |
| 345 // When requesting debug code as a replacement for existing code, we provide | 347 // When requesting debug code as a replacement for existing code, we provide |
| 346 // the same kind as the existing code (to prevent implicit tier-change). | 348 // the same kind as the existing code (to prevent implicit tier-change). |
| 347 if (info->is_debug() && info->shared_info()->is_compiled()) { | 349 if (info->is_debug() && shared->is_compiled()) { |
| 348 return !info->shared_info()->HasBaselineCode(); | 350 return !shared->HasBaselineCode(); |
| 349 } | 351 } |
| 350 | 352 |
| 351 // Code destined for TurboFan should be compiled with Ignition first. | 353 // Code destined for TurboFan should be compiled with Ignition first. |
| 352 if (UseTurboFan(info->shared_info())) return true; | 354 if (UseTurboFan(shared)) return true; |
| 353 | 355 |
| 354 // Only use Ignition for any other function if FLAG_ignition is true. | 356 // Only use Ignition for any other function if FLAG_ignition is true. |
| 355 if (!FLAG_ignition) return false; | 357 if (!FLAG_ignition) return false; |
| 356 | 358 |
| 357 // Checks whether top level functions should be passed by the filter. | 359 // Checks whether top level functions should be passed by the filter. |
| 358 if (info->shared_info()->is_toplevel()) { | 360 if (shared->is_toplevel()) { |
| 359 Vector<const char> filter = CStrVector(FLAG_ignition_filter); | 361 Vector<const char> filter = CStrVector(FLAG_ignition_filter); |
| 360 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); | 362 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); |
| 361 } | 363 } |
| 362 | 364 |
| 363 // Finally respect the filter. | 365 // Finally respect the filter. |
| 364 return info->shared_info()->PassesFilter(FLAG_ignition_filter); | 366 return shared->PassesFilter(FLAG_ignition_filter); |
| 365 } | 367 } |
| 366 | 368 |
| 367 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { | 369 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { |
| 368 // Function should have been parsed and analyzed before creating a compilation | 370 // Function should have been parsed and analyzed before creating a compilation |
| 369 // job. | 371 // job. |
| 370 DCHECK_NOT_NULL(info->literal()); | 372 DCHECK_NOT_NULL(info->literal()); |
| 371 DCHECK_NOT_NULL(info->scope()); | 373 DCHECK_NOT_NULL(info->scope()); |
| 372 | 374 |
| 373 EnsureFeedbackMetadata(info); | 375 EnsureFeedbackMetadata(info); |
| 374 if (ShouldUseIgnition(info)) { | 376 if (ShouldUseIgnition(info)) { |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 parse_info->literal())) { | 522 parse_info->literal())) { |
| 521 return false; | 523 return false; |
| 522 } | 524 } |
| 523 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); | 525 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); |
| 524 if (!shared_info.is_null()) { | 526 if (!shared_info.is_null()) { |
| 525 FunctionLiteral* lit = parse_info->literal(); | 527 FunctionLiteral* lit = parse_info->literal(); |
| 526 shared_info->set_ast_node_count(lit->ast_node_count()); | 528 shared_info->set_ast_node_count(lit->ast_node_count()); |
| 527 if (lit->dont_optimize_reason() != kNoReason) { | 529 if (lit->dont_optimize_reason() != kNoReason) { |
| 528 shared_info->DisableOptimization(lit->dont_optimize_reason()); | 530 shared_info->DisableOptimization(lit->dont_optimize_reason()); |
| 529 } | 531 } |
| 530 if (lit->flags() & AstProperties::kDontCrankshaft) { | 532 if (lit->flags() & AstProperties::kMustUseIgnitionTurbo) { |
| 531 shared_info->set_dont_crankshaft(true); | 533 shared_info->set_must_use_ignition_turbo(true); |
| 532 } | 534 } |
| 533 } | 535 } |
| 534 return true; | 536 return true; |
| 535 } | 537 } |
| 536 | 538 |
| 537 bool GetOptimizedCodeNow(CompilationJob* job) { | 539 bool GetOptimizedCodeNow(CompilationJob* job) { |
| 538 CompilationInfo* info = job->info(); | 540 CompilationInfo* info = job->info(); |
| 539 Isolate* isolate = info->isolate(); | 541 Isolate* isolate = info->isolate(); |
| 540 | 542 |
| 541 // Parsing is not required when optimizing from existing bytecode. | 543 // Parsing is not required when optimizing from existing bytecode. |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 function->ShortPrint(); | 645 function->ShortPrint(); |
| 644 if (!osr_ast_id.IsNone()) { | 646 if (!osr_ast_id.IsNone()) { |
| 645 PrintF(" at OSR AST id %d", osr_ast_id.ToInt()); | 647 PrintF(" at OSR AST id %d", osr_ast_id.ToInt()); |
| 646 } | 648 } |
| 647 PrintF("]\n"); | 649 PrintF("]\n"); |
| 648 } | 650 } |
| 649 return cached_code; | 651 return cached_code; |
| 650 } | 652 } |
| 651 | 653 |
| 652 // Reset profiler ticks, function is no longer considered hot. | 654 // Reset profiler ticks, function is no longer considered hot. |
| 655 DCHECK(shared->is_compiled()); |
| 653 if (shared->HasBaselineCode()) { | 656 if (shared->HasBaselineCode()) { |
| 654 shared->code()->set_profiler_ticks(0); | 657 shared->code()->set_profiler_ticks(0); |
| 655 } else if (shared->HasBytecodeArray()) { | 658 } else if (shared->HasBytecodeArray()) { |
| 656 shared->set_profiler_ticks(0); | 659 shared->set_profiler_ticks(0); |
| 657 } | 660 } |
| 658 | 661 |
| 659 VMState<COMPILER> state(isolate); | 662 VMState<COMPILER> state(isolate); |
| 660 DCHECK(!isolate->has_pending_exception()); | 663 DCHECK(!isolate->has_pending_exception()); |
| 661 PostponeInterruptsScope postpone(isolate); | 664 PostponeInterruptsScope postpone(isolate); |
| 662 bool use_turbofan = UseTurboFan(shared) || ignition_osr; | 665 bool use_turbofan = UseTurboFan(shared) || ignition_osr; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 682 return MaybeHandle<Code>(); | 685 return MaybeHandle<Code>(); |
| 683 } | 686 } |
| 684 | 687 |
| 685 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); | 688 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); |
| 686 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::OptimizeCode); | 689 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::OptimizeCode); |
| 687 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.OptimizeCode"); | 690 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.OptimizeCode"); |
| 688 | 691 |
| 689 // TurboFan can optimize directly from existing bytecode. | 692 // TurboFan can optimize directly from existing bytecode. |
| 690 if (use_turbofan && ShouldUseIgnition(info)) { | 693 if (use_turbofan && ShouldUseIgnition(info)) { |
| 691 if (info->is_osr() && !ignition_osr) return MaybeHandle<Code>(); | 694 if (info->is_osr() && !ignition_osr) return MaybeHandle<Code>(); |
| 692 if (!Compiler::EnsureBytecode(info)) { | 695 DCHECK(shared->HasBytecodeArray()); |
| 693 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); | |
| 694 return MaybeHandle<Code>(); | |
| 695 } | |
| 696 info->MarkAsOptimizeFromBytecode(); | 696 info->MarkAsOptimizeFromBytecode(); |
| 697 } | 697 } |
| 698 | 698 |
| 699 // Verify that OSR compilations are delegated to the correct graph builder. | 699 // Verify that OSR compilations are delegated to the correct graph builder. |
| 700 // Depending on the underlying frame the semantics of the {BailoutId} differ | 700 // Depending on the underlying frame the semantics of the {BailoutId} differ |
| 701 // and the various graph builders hard-code a certain semantic: | 701 // and the various graph builders hard-code a certain semantic: |
| 702 // - Interpreter : The BailoutId represents a bytecode offset. | 702 // - Interpreter : The BailoutId represents a bytecode offset. |
| 703 // - FullCodegen : The BailoutId represents the id of an AST node. | 703 // - FullCodegen : The BailoutId represents the id of an AST node. |
| 704 DCHECK_IMPLIES(info->is_osr() && ignition_osr, | 704 DCHECK_IMPLIES(info->is_osr() && ignition_osr, |
| 705 info->is_optimizing_from_bytecode()); | 705 info->is_optimizing_from_bytecode()); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 if (function->shared()->code()->kind() == Code::FUNCTION) { | 815 if (function->shared()->code()->kind() == Code::FUNCTION) { |
| 816 return Handle<Code>(function->shared()->code()); | 816 return Handle<Code>(function->shared()->code()); |
| 817 } | 817 } |
| 818 | 818 |
| 819 // We do not switch to baseline code when the debugger might have created a | 819 // We do not switch to baseline code when the debugger might have created a |
| 820 // copy of the bytecode with break slots to be able to set break points. | 820 // copy of the bytecode with break slots to be able to set break points. |
| 821 if (function->shared()->HasDebugInfo()) { | 821 if (function->shared()->HasDebugInfo()) { |
| 822 return MaybeHandle<Code>(); | 822 return MaybeHandle<Code>(); |
| 823 } | 823 } |
| 824 | 824 |
| 825 // TODO(4280): For now we do not switch generators or async functions to | 825 // Don't generate full-codegen code for functions it can't support. |
| 826 // baseline code because there might be suspended activations stored in | 826 if (function->shared()->must_use_ignition_turbo()) { |
| 827 // generator objects on the heap. We could eventually go directly to | |
| 828 // TurboFan in this case. | |
| 829 if (IsResumableFunction(function->shared()->kind())) { | |
| 830 return MaybeHandle<Code>(); | 827 return MaybeHandle<Code>(); |
| 831 } | 828 } |
| 829 DCHECK(!IsResumableFunction(function->shared()->kind())); |
| 832 | 830 |
| 833 if (FLAG_trace_opt) { | 831 if (FLAG_trace_opt) { |
| 834 OFStream os(stdout); | 832 OFStream os(stdout); |
| 835 os << "[switching method " << Brief(*function) << " to baseline code]" | 833 os << "[switching method " << Brief(*function) << " to baseline code]" |
| 836 << std::endl; | 834 << std::endl; |
| 837 } | 835 } |
| 838 | 836 |
| 839 // Parse and update CompilationInfo with the results. | 837 // Parse and update CompilationInfo with the results. |
| 840 if (!Parser::ParseStatic(info.parse_info())) return MaybeHandle<Code>(); | 838 if (!Parser::ParseStatic(info.parse_info())) return MaybeHandle<Code>(); |
| 841 Handle<SharedFunctionInfo> shared = info.shared_info(); | 839 Handle<SharedFunctionInfo> shared = info.shared_info(); |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1187 | 1185 |
| 1188 // Restore the original function info list in order to remain side-effect | 1186 // Restore the original function info list in order to remain side-effect |
| 1189 // free as much as possible, since some code expects the old shared function | 1187 // free as much as possible, since some code expects the old shared function |
| 1190 // infos to stick around. | 1188 // infos to stick around. |
| 1191 script->set_shared_function_infos(*old_function_infos); | 1189 script->set_shared_function_infos(*old_function_infos); |
| 1192 | 1190 |
| 1193 return infos; | 1191 return infos; |
| 1194 } | 1192 } |
| 1195 | 1193 |
| 1196 bool Compiler::EnsureBytecode(CompilationInfo* info) { | 1194 bool Compiler::EnsureBytecode(CompilationInfo* info) { |
| 1197 if (!ShouldUseIgnition(info)) return false; | 1195 if (!info->shared_info()->is_compiled()) { |
| 1198 if (!info->shared_info()->HasBytecodeArray()) { | |
| 1199 Handle<Code> original_code(info->shared_info()->code()); | |
| 1200 if (GetUnoptimizedCode(info).is_null()) return false; | 1196 if (GetUnoptimizedCode(info).is_null()) return false; |
| 1201 if (info->shared_info()->HasAsmWasmData()) return false; | 1197 if (info->shared_info()->HasAsmWasmData()) return false; |
| 1202 DCHECK(info->shared_info()->is_compiled()); | |
| 1203 if (original_code->kind() == Code::FUNCTION) { | |
| 1204 // Generating bytecode will install the {InterpreterEntryTrampoline} as | |
| 1205 // shared code on the function. To avoid an implicit tier down we restore | |
| 1206 // original baseline code in case it existed beforehand. | |
| 1207 info->shared_info()->ReplaceCode(*original_code); | |
| 1208 } | |
| 1209 } | 1198 } |
| 1210 DCHECK(info->shared_info()->HasBytecodeArray()); | 1199 DCHECK(info->shared_info()->is_compiled()); |
| 1211 return true; | 1200 DCHECK_EQ(ShouldUseIgnition(info), info->shared_info()->HasBytecodeArray()); |
| 1201 return info->shared_info()->HasBytecodeArray(); |
| 1212 } | 1202 } |
| 1213 | 1203 |
| 1214 // TODO(turbofan): In the future, unoptimized code with deopt support could | 1204 // TODO(turbofan): In the future, unoptimized code with deopt support could |
| 1215 // be generated lazily once deopt is triggered. | 1205 // be generated lazily once deopt is triggered. |
| 1216 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 1206 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
| 1217 DCHECK_NOT_NULL(info->literal()); | 1207 DCHECK_NOT_NULL(info->literal()); |
| 1218 DCHECK_NOT_NULL(info->scope()); | 1208 DCHECK_NOT_NULL(info->scope()); |
| 1219 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1209 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 1220 if (!shared->has_deoptimization_support()) { | 1210 if (!shared->has_deoptimization_support()) { |
| 1221 Zone zone(info->isolate()->allocator(), ZONE_NAME); | 1211 Zone zone(info->isolate()->allocator(), ZONE_NAME); |
| 1222 CompilationInfo unoptimized(info->parse_info(), info->closure()); | 1212 CompilationInfo unoptimized(info->parse_info(), info->closure()); |
| 1223 unoptimized.EnableDeoptimizationSupport(); | 1213 unoptimized.EnableDeoptimizationSupport(); |
| 1224 | 1214 |
| 1225 // TODO(4280): For now we do not switch generators or async functions to | 1215 // Don't generate full-codegen code for functions it can't support. |
| 1226 // baseline code because there might be suspended activations stored in | 1216 if (shared->must_use_ignition_turbo()) return false; |
| 1227 // generator objects on the heap. We could eventually go directly to | 1217 DCHECK(!IsResumableFunction(shared->kind())); |
| 1228 // TurboFan in this case. | |
| 1229 if (IsResumableFunction(shared->kind())) return false; | |
| 1230 | 1218 |
| 1231 // When we call PrepareForSerializing below, we will change the shared | 1219 // When we call PrepareForSerializing below, we will change the shared |
| 1232 // ParseInfo. Make sure to reset it. | 1220 // ParseInfo. Make sure to reset it. |
| 1233 bool old_will_serialize_value = info->parse_info()->will_serialize(); | 1221 bool old_will_serialize_value = info->parse_info()->will_serialize(); |
| 1234 | 1222 |
| 1235 // If the current code has reloc info for serialization, also include | 1223 // If the current code has reloc info for serialization, also include |
| 1236 // reloc info for serialization for the new code, so that deopt support | 1224 // reloc info for serialization for the new code, so that deopt support |
| 1237 // can be added without losing IC state. | 1225 // can be added without losing IC state. |
| 1238 if (shared->code()->kind() == Code::FUNCTION && | 1226 if (shared->code()->kind() == Code::FUNCTION && |
| 1239 shared->code()->has_reloc_info_for_serialization()) { | 1227 shared->code()->has_reloc_info_for_serialization()) { |
| 1240 unoptimized.PrepareForSerializing(); | 1228 unoptimized.PrepareForSerializing(); |
| 1241 } | 1229 } |
| 1242 EnsureFeedbackMetadata(&unoptimized); | 1230 EnsureFeedbackMetadata(&unoptimized); |
| 1231 |
| 1232 // Ensure we generate and install bytecode first if the function should use |
| 1233 // Ignition to avoid implicit tier-down. |
| 1234 if (!shared->is_compiled() && ShouldUseIgnition(info) && |
| 1235 !GenerateUnoptimizedCode(info)) { |
| 1236 return false; |
| 1237 } |
| 1238 |
| 1243 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; | 1239 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; |
| 1244 | 1240 |
| 1245 info->parse_info()->set_will_serialize(old_will_serialize_value); | 1241 info->parse_info()->set_will_serialize(old_will_serialize_value); |
| 1246 | 1242 |
| 1247 // The scope info might not have been set if a lazily compiled | 1243 // The scope info might not have been set if a lazily compiled |
| 1248 // function is inlined before being called for the first time. | 1244 // function is inlined before being called for the first time. |
| 1249 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { | 1245 if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) { |
| 1250 InstallSharedScopeInfo(info, shared); | 1246 InstallSharedScopeInfo(info, shared); |
| 1251 } | 1247 } |
| 1252 | 1248 |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1707 return true; | 1703 return true; |
| 1708 } | 1704 } |
| 1709 return false; | 1705 return false; |
| 1710 } | 1706 } |
| 1711 } | 1707 } |
| 1712 | 1708 |
| 1713 void Compiler::PostInstantiation(Handle<JSFunction> function, | 1709 void Compiler::PostInstantiation(Handle<JSFunction> function, |
| 1714 PretenureFlag pretenure) { | 1710 PretenureFlag pretenure) { |
| 1715 Handle<SharedFunctionInfo> shared(function->shared()); | 1711 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1716 | 1712 |
| 1717 if (FLAG_always_opt && shared->allows_lazy_compilation()) { | 1713 if (FLAG_always_opt && shared->allows_lazy_compilation() && |
| 1714 function->shared()->is_compiled()) { |
| 1718 function->MarkForOptimization(); | 1715 function->MarkForOptimization(); |
| 1719 } | 1716 } |
| 1720 | 1717 |
| 1721 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( | 1718 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( |
| 1722 function->context()->native_context(), BailoutId::None()); | 1719 function->context()->native_context(), BailoutId::None()); |
| 1723 if (cached.code != nullptr) { | 1720 if (cached.code != nullptr) { |
| 1724 // Caching of optimized code enabled and optimized code found. | 1721 // Caching of optimized code enabled and optimized code found. |
| 1725 DCHECK(!cached.code->marked_for_deoptimization()); | 1722 DCHECK(!cached.code->marked_for_deoptimization()); |
| 1726 DCHECK(function->shared()->is_compiled()); | 1723 DCHECK(function->shared()->is_compiled()); |
| 1727 function->ReplaceCode(cached.code); | 1724 function->ReplaceCode(cached.code); |
| 1728 } | 1725 } |
| 1729 | 1726 |
| 1730 if (cached.literals != nullptr) { | 1727 if (cached.literals != nullptr) { |
| 1731 DCHECK(shared->is_compiled()); | 1728 DCHECK(shared->is_compiled()); |
| 1732 function->set_literals(cached.literals); | 1729 function->set_literals(cached.literals); |
| 1733 } else if (shared->is_compiled()) { | 1730 } else if (shared->is_compiled()) { |
| 1734 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1731 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
| 1735 JSFunction::EnsureLiterals(function); | 1732 JSFunction::EnsureLiterals(function); |
| 1736 } | 1733 } |
| 1737 } | 1734 } |
| 1738 | 1735 |
| 1739 } // namespace internal | 1736 } // namespace internal |
| 1740 } // namespace v8 | 1737 } // namespace v8 |
| OLD | NEW |