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/asmjs/asm-js.h" | 9 #include "src/asmjs/asm-js.h" |
10 #include "src/asmjs/asm-typer.h" | 10 #include "src/asmjs/asm-typer.h" |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 info->isolate(), info->literal()->feedback_vector_spec()); | 434 info->isolate(), info->literal()->feedback_vector_spec()); |
435 info->shared_info()->set_feedback_metadata(*feedback_metadata); | 435 info->shared_info()->set_feedback_metadata(*feedback_metadata); |
436 } | 436 } |
437 | 437 |
438 // It's very important that recompiles do not alter the structure of the type | 438 // It's very important that recompiles do not alter the structure of the type |
439 // feedback vector. Verify that the structure fits the function literal. | 439 // feedback vector. Verify that the structure fits the function literal. |
440 CHECK(!info->shared_info()->feedback_metadata()->SpecDiffersFrom( | 440 CHECK(!info->shared_info()->feedback_metadata()->SpecDiffersFrom( |
441 info->literal()->feedback_vector_spec())); | 441 info->literal()->feedback_vector_spec())); |
442 } | 442 } |
443 | 443 |
444 bool UseIgnition(CompilationInfo* info) { | 444 bool ShouldUseIgnition(CompilationInfo* info) { |
445 DCHECK(info->has_shared_info()); | 445 DCHECK(info->has_shared_info()); |
446 | 446 |
447 // When requesting debug code as a replacement for existing code, we provide | 447 // When requesting debug code as a replacement for existing code, we provide |
448 // the same kind as the existing code (to prevent implicit tier-change). | 448 // the same kind as the existing code (to prevent implicit tier-change). |
449 if (info->is_debug() && info->shared_info()->is_compiled()) { | 449 if (info->is_debug() && info->shared_info()->is_compiled()) { |
450 return info->shared_info()->HasBytecodeArray(); | 450 return info->shared_info()->HasBytecodeArray(); |
451 } | 451 } |
452 | 452 |
453 // For generator or async functions we might avoid Ignition wholesale. | 453 // For generator or async functions we might avoid Ignition wholesale. |
454 if (info->shared_info()->is_resumable() && !FLAG_ignition_generators) { | 454 if (info->shared_info()->is_resumable() && !FLAG_ignition_generators) { |
(...skipping 27 matching lines...) Expand all Loading... |
482 EnsureFeedbackMetadata(info); | 482 EnsureFeedbackMetadata(info); |
483 if (FLAG_validate_asm && info->scope()->asm_module()) { | 483 if (FLAG_validate_asm && info->scope()->asm_module()) { |
484 MaybeHandle<FixedArray> wasm_data; | 484 MaybeHandle<FixedArray> wasm_data; |
485 wasm_data = AsmJs::ConvertAsmToWasm(info->parse_info()); | 485 wasm_data = AsmJs::ConvertAsmToWasm(info->parse_info()); |
486 if (!wasm_data.is_null()) { | 486 if (!wasm_data.is_null()) { |
487 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); | 487 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); |
488 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); | 488 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); |
489 return true; | 489 return true; |
490 } | 490 } |
491 } | 491 } |
492 if (FLAG_ignition && UseIgnition(info)) { | 492 if (FLAG_ignition && ShouldUseIgnition(info)) { |
493 success = interpreter::Interpreter::MakeBytecode(info); | 493 success = interpreter::Interpreter::MakeBytecode(info); |
494 } else { | 494 } else { |
495 success = FullCodeGenerator::MakeCode(info); | 495 success = FullCodeGenerator::MakeCode(info); |
496 } | 496 } |
497 if (success) { | 497 if (success) { |
498 Isolate* isolate = info->isolate(); | 498 Isolate* isolate = info->isolate(); |
499 Counters* counters = isolate->counters(); | 499 Counters* counters = isolate->counters(); |
500 // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually. | 500 // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually. |
501 counters->total_baseline_code_size()->Increment(CodeAndMetadataSize(info)); | 501 counters->total_baseline_code_size()->Increment(CodeAndMetadataSize(info)); |
502 counters->total_baseline_compile_count()->Increment(1); | 502 counters->total_baseline_compile_count()->Increment(1); |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 info->AbortOptimization(kOptimizedTooManyTimes); | 794 info->AbortOptimization(kOptimizedTooManyTimes); |
795 return MaybeHandle<Code>(); | 795 return MaybeHandle<Code>(); |
796 } | 796 } |
797 | 797 |
798 CanonicalHandleScope canonical(isolate); | 798 CanonicalHandleScope canonical(isolate); |
799 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); | 799 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); |
800 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::OptimizeCode); | 800 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::OptimizeCode); |
801 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.OptimizeCode"); | 801 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.OptimizeCode"); |
802 | 802 |
803 // TurboFan can optimize directly from existing bytecode. | 803 // TurboFan can optimize directly from existing bytecode. |
804 if (FLAG_turbo_from_bytecode && use_turbofan && | 804 if (FLAG_turbo_from_bytecode && use_turbofan && ShouldUseIgnition(info)) { |
805 info->shared_info()->HasBytecodeArray()) { | 805 if (!Compiler::EnsureBytecode(info)) { |
| 806 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); |
| 807 return MaybeHandle<Code>(); |
| 808 } |
806 info->MarkAsOptimizeFromBytecode(); | 809 info->MarkAsOptimizeFromBytecode(); |
807 } | 810 } |
808 | 811 |
809 if (IsEvalToplevel(shared)) { | 812 if (IsEvalToplevel(shared)) { |
810 parse_info->set_eval(); | 813 parse_info->set_eval(); |
811 if (function->context()->IsNativeContext()) parse_info->set_global(); | 814 if (function->context()->IsNativeContext()) parse_info->set_global(); |
812 parse_info->set_toplevel(); | 815 parse_info->set_toplevel(); |
813 parse_info->set_allow_lazy_parsing(false); | 816 parse_info->set_allow_lazy_parsing(false); |
814 parse_info->set_lazy(false); | 817 parse_info->set_lazy(false); |
815 } | 818 } |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 } | 1340 } |
1338 | 1341 |
1339 // Restore the original function info list in order to remain side-effect | 1342 // Restore the original function info list in order to remain side-effect |
1340 // free as much as possible, since some code expects the old shared function | 1343 // free as much as possible, since some code expects the old shared function |
1341 // infos to stick around. | 1344 // infos to stick around. |
1342 script->set_shared_function_infos(*old_function_infos); | 1345 script->set_shared_function_infos(*old_function_infos); |
1343 | 1346 |
1344 return infos; | 1347 return infos; |
1345 } | 1348 } |
1346 | 1349 |
| 1350 bool Compiler::EnsureBytecode(CompilationInfo* info) { |
| 1351 DCHECK(ShouldUseIgnition(info)); |
| 1352 if (!info->shared_info()->HasBytecodeArray()) { |
| 1353 DCHECK(!info->shared_info()->is_compiled()); |
| 1354 if (GetUnoptimizedCode(info).is_null()) return false; |
| 1355 } |
| 1356 DCHECK(info->shared_info()->HasBytecodeArray()); |
| 1357 return true; |
| 1358 } |
| 1359 |
1347 // TODO(turbofan): In the future, unoptimized code with deopt support could | 1360 // TODO(turbofan): In the future, unoptimized code with deopt support could |
1348 // be generated lazily once deopt is triggered. | 1361 // be generated lazily once deopt is triggered. |
1349 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 1362 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
1350 DCHECK_NOT_NULL(info->literal()); | 1363 DCHECK_NOT_NULL(info->literal()); |
1351 DCHECK_NOT_NULL(info->scope()); | 1364 DCHECK_NOT_NULL(info->scope()); |
1352 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1365 Handle<SharedFunctionInfo> shared = info->shared_info(); |
1353 if (!shared->has_deoptimization_support()) { | 1366 if (!shared->has_deoptimization_support()) { |
1354 Zone zone(info->isolate()->allocator()); | 1367 Zone zone(info->isolate()->allocator()); |
1355 CompilationInfo unoptimized(info->parse_info(), info->closure()); | 1368 CompilationInfo unoptimized(info->parse_info(), info->closure()); |
1356 unoptimized.EnableDeoptimizationSupport(); | 1369 unoptimized.EnableDeoptimizationSupport(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1398 // Install compilation result on the shared function info | 1411 // Install compilation result on the shared function info |
1399 shared->EnableDeoptimizationSupport(*unoptimized.code()); | 1412 shared->EnableDeoptimizationSupport(*unoptimized.code()); |
1400 | 1413 |
1401 // The existing unoptimized code was replaced with the new one. | 1414 // The existing unoptimized code was replaced with the new one. |
1402 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, | 1415 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, |
1403 &unoptimized); | 1416 &unoptimized); |
1404 } | 1417 } |
1405 return true; | 1418 return true; |
1406 } | 1419 } |
1407 | 1420 |
| 1421 // static |
| 1422 Compiler::CompilationTier Compiler::NextCompilationTier(JSFunction* function) { |
| 1423 Handle<SharedFunctionInfo> shared(function->shared(), function->GetIsolate()); |
| 1424 if (shared->code()->is_interpreter_trampoline_builtin()) { |
| 1425 if (FLAG_turbo_from_bytecode && UseTurboFan(shared)) { |
| 1426 return OPTIMIZED; |
| 1427 } else { |
| 1428 return BASELINE; |
| 1429 } |
| 1430 } else { |
| 1431 return OPTIMIZED; |
| 1432 } |
| 1433 } |
| 1434 |
1408 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( | 1435 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( |
1409 Handle<String> source, Handle<SharedFunctionInfo> outer_info, | 1436 Handle<String> source, Handle<SharedFunctionInfo> outer_info, |
1410 Handle<Context> context, LanguageMode language_mode, | 1437 Handle<Context> context, LanguageMode language_mode, |
1411 ParseRestriction restriction, int eval_scope_position, int eval_position, | 1438 ParseRestriction restriction, int eval_scope_position, int eval_position, |
1412 int line_offset, int column_offset, Handle<Object> script_name, | 1439 int line_offset, int column_offset, Handle<Object> script_name, |
1413 ScriptOriginOptions options) { | 1440 ScriptOriginOptions options) { |
1414 Isolate* isolate = source->GetIsolate(); | 1441 Isolate* isolate = source->GetIsolate(); |
1415 int source_length = source->length(); | 1442 int source_length = source->length(); |
1416 isolate->counters()->total_eval_size()->Increment(source_length); | 1443 isolate->counters()->total_eval_size()->Increment(source_length); |
1417 isolate->counters()->total_compile_size()->Increment(source_length); | 1444 isolate->counters()->total_compile_size()->Increment(source_length); |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1889 DCHECK(shared->is_compiled()); | 1916 DCHECK(shared->is_compiled()); |
1890 function->set_literals(cached.literals); | 1917 function->set_literals(cached.literals); |
1891 } else if (shared->is_compiled()) { | 1918 } else if (shared->is_compiled()) { |
1892 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1919 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
1893 JSFunction::EnsureLiterals(function); | 1920 JSFunction::EnsureLiterals(function); |
1894 } | 1921 } |
1895 } | 1922 } |
1896 | 1923 |
1897 } // namespace internal | 1924 } // namespace internal |
1898 } // namespace v8 | 1925 } // namespace v8 |
OLD | NEW |