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 |