Chromium Code Reviews| 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 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 376 // Finally respect the filter. | 376 // Finally respect the filter. |
| 377 return shared->PassesFilter(FLAG_ignition_filter); | 377 return shared->PassesFilter(FLAG_ignition_filter); |
| 378 } | 378 } |
| 379 | 379 |
| 380 bool UseAsmWasm(DeclarationScope* scope, Handle<SharedFunctionInfo> shared_info, | 380 bool UseAsmWasm(DeclarationScope* scope, Handle<SharedFunctionInfo> shared_info, |
| 381 bool is_debug) { | 381 bool is_debug) { |
| 382 return FLAG_validate_asm && scope->asm_module() && | 382 return FLAG_validate_asm && scope->asm_module() && |
| 383 !shared_info->is_asm_wasm_broken() && !is_debug; | 383 !shared_info->is_asm_wasm_broken() && !is_debug; |
| 384 } | 384 } |
| 385 | 385 |
| 386 bool UseCompilerDispatcher(CompilerDispatcher* dispatcher, | 386 bool UseCompilerDispatcher(Compiler::ConcurrencyMode inner_function_mode, |
| 387 CompilerDispatcher* dispatcher, | |
| 387 DeclarationScope* scope, | 388 DeclarationScope* scope, |
| 388 Handle<SharedFunctionInfo> shared_info, | 389 Handle<SharedFunctionInfo> shared_info, |
| 389 bool is_debug, bool will_serialize) { | 390 bool is_debug, bool will_serialize) { |
| 390 return FLAG_compiler_dispatcher_eager_inner && dispatcher->IsEnabled() && | 391 return FLAG_compiler_dispatcher_eager_inner && |
| 391 !is_debug && !will_serialize && | 392 inner_function_mode == Compiler::CONCURRENT && |
| 393 dispatcher->IsEnabled() && !is_debug && !will_serialize && | |
| 392 !UseAsmWasm(scope, shared_info, is_debug); | 394 !UseAsmWasm(scope, shared_info, is_debug); |
| 393 } | 395 } |
| 394 | 396 |
| 395 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { | 397 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { |
| 396 // Function should have been parsed and analyzed before creating a compilation | 398 // Function should have been parsed and analyzed before creating a compilation |
| 397 // job. | 399 // job. |
| 398 DCHECK_NOT_NULL(info->literal()); | 400 DCHECK_NOT_NULL(info->literal()); |
| 399 DCHECK_NOT_NULL(info->scope()); | 401 DCHECK_NOT_NULL(info->scope()); |
| 400 | 402 |
| 401 if (ShouldUseIgnition(info)) { | 403 if (ShouldUseIgnition(info)) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 502 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; | 504 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; |
| 503 if (FinalizeUnoptimizedCompilationJob(job.get()) != | 505 if (FinalizeUnoptimizedCompilationJob(job.get()) != |
| 504 CompilationJob::SUCCEEDED) { | 506 CompilationJob::SUCCEEDED) { |
| 505 return false; | 507 return false; |
| 506 } | 508 } |
| 507 return true; | 509 return true; |
| 508 } | 510 } |
| 509 | 511 |
| 510 bool CompileUnoptimizedInnerFunctions( | 512 bool CompileUnoptimizedInnerFunctions( |
| 511 Compiler::EagerInnerFunctionLiterals* literals, | 513 Compiler::EagerInnerFunctionLiterals* literals, |
| 514 Compiler::ConcurrencyMode inner_function_mode, | |
| 512 CompilationInfo* outer_info) { | 515 CompilationInfo* outer_info) { |
| 513 Isolate* isolate = outer_info->isolate(); | 516 Isolate* isolate = outer_info->isolate(); |
| 514 Handle<Script> script = outer_info->script(); | 517 Handle<Script> script = outer_info->script(); |
| 515 bool is_debug = outer_info->is_debug(); | 518 bool is_debug = outer_info->is_debug(); |
| 516 bool will_serialize = outer_info->will_serialize(); | 519 bool will_serialize = outer_info->will_serialize(); |
| 517 RuntimeCallTimerScope runtimeTimer(isolate, | 520 RuntimeCallTimerScope runtimeTimer(isolate, |
| 518 &RuntimeCallStats::CompileInnerFunction); | 521 &RuntimeCallStats::CompileInnerFunction); |
| 519 | 522 |
| 520 for (auto it : *literals) { | 523 for (auto it : *literals) { |
| 521 FunctionLiteral* literal = it->value(); | 524 FunctionLiteral* literal = it->value(); |
| 522 Handle<SharedFunctionInfo> shared = | 525 Handle<SharedFunctionInfo> shared = |
| 523 Compiler::GetSharedFunctionInfo(literal, script, outer_info); | 526 Compiler::GetSharedFunctionInfo(literal, script, outer_info); |
| 524 if (shared->is_compiled()) continue; | 527 if (shared->is_compiled()) continue; |
| 525 | 528 |
| 526 // The {literal} has already been numbered because AstNumbering decends into | 529 // The {literal} has already been numbered because AstNumbering decends into |
| 527 // eagerly compiled function literals. | 530 // eagerly compiled function literals. |
| 528 SetSharedFunctionFlagsFromLiteral(literal, shared); | 531 SetSharedFunctionFlagsFromLiteral(literal, shared); |
| 529 | 532 |
| 530 // Try to enqueue the eager function on the compiler dispatcher. | 533 // Try to enqueue the eager function on the compiler dispatcher. |
| 531 CompilerDispatcher* dispatcher = isolate->compiler_dispatcher(); | 534 CompilerDispatcher* dispatcher = isolate->compiler_dispatcher(); |
| 532 if (UseCompilerDispatcher(dispatcher, literal->scope(), shared, is_debug, | 535 if (UseCompilerDispatcher(inner_function_mode, dispatcher, literal->scope(), |
| 533 will_serialize) && | 536 shared, is_debug, will_serialize) && |
| 534 dispatcher->EnqueueAndStep(shared, literal)) { | 537 dispatcher->EnqueueAndStep(shared, literal)) { |
| 535 // If we have successfully queued up the function for compilation on the | 538 // If we have successfully queued up the function for compilation on the |
| 536 // compiler dispatcher then we are done. | 539 // compiler dispatcher then we are done. |
| 537 continue; | 540 continue; |
| 538 } else { | 541 } else { |
| 539 // Otherwise generate unoptimized code now. | 542 // Otherwise generate unoptimized code now. |
| 540 ParseInfo parse_info(script); | 543 ParseInfo parse_info(script); |
| 541 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 544 CompilationInfo info(parse_info.zone(), &parse_info, |
| 545 Handle<JSFunction>::null()); | |
| 542 | 546 |
| 543 parse_info.set_literal(literal); | 547 parse_info.set_literal(literal); |
| 544 parse_info.set_shared_info(shared); | 548 parse_info.set_shared_info(shared); |
| 545 parse_info.set_function_literal_id(shared->function_literal_id()); | 549 parse_info.set_function_literal_id(shared->function_literal_id()); |
| 546 parse_info.set_language_mode(literal->scope()->language_mode()); | 550 parse_info.set_language_mode(literal->scope()->language_mode()); |
| 547 parse_info.set_ast_value_factory( | 551 parse_info.set_ast_value_factory( |
| 548 outer_info->parse_info()->ast_value_factory()); | 552 outer_info->parse_info()->ast_value_factory()); |
| 549 parse_info.set_ast_value_factory_owned(false); | 553 parse_info.set_ast_value_factory_owned(false); |
| 550 | 554 |
| 551 if (will_serialize) info.PrepareForSerializing(); | 555 if (will_serialize) info.PrepareForSerializing(); |
| 552 if (is_debug) info.MarkAsDebug(); | 556 if (is_debug) info.MarkAsDebug(); |
| 553 | 557 |
| 554 if (!GenerateUnoptimizedCode(&info)) { | 558 if (!GenerateUnoptimizedCode(&info)) { |
| 555 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 559 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
| 556 return false; | 560 return false; |
| 557 } | 561 } |
| 558 } | 562 } |
| 559 } | 563 } |
| 560 return true; | 564 return true; |
| 561 } | 565 } |
| 562 | 566 |
| 563 bool CompileUnoptimizedCode(CompilationInfo* info) { | 567 bool InnerFunctionIsAsmModule( |
| 568 ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* literals) { | |
| 569 for (auto it : *literals) { | |
| 570 FunctionLiteral* literal = it->value(); | |
| 571 if (literal->scope()->IsAsmModule()) return true; | |
| 572 } | |
| 573 return false; | |
| 574 } | |
| 575 | |
| 576 bool CompileUnoptimizedCode(CompilationInfo* info, | |
| 577 Compiler::ConcurrencyMode inner_function_mode) { | |
| 564 Isolate* isolate = info->isolate(); | 578 Isolate* isolate = info->isolate(); |
| 565 DCHECK(AllowCompilation::IsAllowed(isolate)); | 579 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 566 | 580 |
| 567 Compiler::EagerInnerFunctionLiterals inner_literals; | 581 Compiler::EagerInnerFunctionLiterals inner_literals; |
| 568 if (!Compiler::Analyze(info->parse_info(), &inner_literals) || | 582 if (!Compiler::Analyze(info->parse_info(), &inner_literals)) { |
| 569 !CompileUnoptimizedInnerFunctions(&inner_literals, info) || | 583 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
| 584 return false; | |
| 585 } | |
| 586 | |
| 587 // Disable concurrent inner compilation for asm-wasm code. | |
| 588 // TODO(rmcilroy,bradnelson): Remove this AsmWasm check once the asm-wasm | |
| 589 // builder doesn't do parsing when visiting function declarations. | |
| 590 if (info->scope()->IsAsmModule() || | |
| 591 InnerFunctionIsAsmModule(&inner_literals)) { | |
| 592 inner_function_mode = Compiler::NOT_CONCURRENT; | |
| 593 } | |
| 594 | |
| 595 if (inner_function_mode == Compiler::CONCURRENT) { | |
| 596 // Seal the parse zone so that it can be shared by parallel inner function | |
| 597 // compilation jobs. | |
| 598 DCHECK_NE(info->parse_info()->zone(), info->zone()); | |
| 599 info->parse_info()->zone()->Seal(); | |
| 600 } | |
| 601 | |
| 602 if (!CompileUnoptimizedInnerFunctions(&inner_literals, inner_function_mode, | |
| 603 info) || | |
| 570 !GenerateUnoptimizedCode(info)) { | 604 !GenerateUnoptimizedCode(info)) { |
| 571 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 605 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
| 572 return false; | 606 return false; |
| 573 } | 607 } |
| 574 | 608 |
| 575 // TODO(rmcilroy): Remove this once the enqueued tasks can keep the parsed | 609 // TODO(rmcilroy): Remove this once the enqueued tasks can keep the parsed |
| 576 // zone and handles alive and replace with a check in CompileLazy to finish | 610 // zone and handles alive and replace with a check in CompileLazy to finish |
| 577 // the task itself. | 611 // the task itself. |
| 578 RuntimeCallTimerScope runtimeTimer( | 612 RuntimeCallTimerScope runtimeTimer( |
| 579 isolate, &RuntimeCallStats::CompileWaitForDispatcher); | 613 isolate, &RuntimeCallStats::CompileWaitForDispatcher); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 593 DCHECK_EQ(info->script()->shared_function_infos()->length(), | 627 DCHECK_EQ(info->script()->shared_function_infos()->length(), |
| 594 info->max_function_literal_id() + 1); | 628 info->max_function_literal_id() + 1); |
| 595 return; | 629 return; |
| 596 } | 630 } |
| 597 Isolate* isolate = info->isolate(); | 631 Isolate* isolate = info->isolate(); |
| 598 Handle<FixedArray> infos( | 632 Handle<FixedArray> infos( |
| 599 isolate->factory()->NewFixedArray(info->max_function_literal_id() + 1)); | 633 isolate->factory()->NewFixedArray(info->max_function_literal_id() + 1)); |
| 600 info->script()->set_shared_function_infos(*infos); | 634 info->script()->set_shared_function_infos(*infos); |
| 601 } | 635 } |
| 602 | 636 |
| 603 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { | 637 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode( |
| 638 CompilationInfo* info, Compiler::ConcurrencyMode inner_function_mode) { | |
| 604 RuntimeCallTimerScope runtimeTimer( | 639 RuntimeCallTimerScope runtimeTimer( |
| 605 info->isolate(), &RuntimeCallStats::CompileGetUnoptimizedCode); | 640 info->isolate(), &RuntimeCallStats::CompileGetUnoptimizedCode); |
| 606 VMState<COMPILER> state(info->isolate()); | 641 VMState<COMPILER> state(info->isolate()); |
| 607 PostponeInterruptsScope postpone(info->isolate()); | 642 PostponeInterruptsScope postpone(info->isolate()); |
| 608 | 643 |
| 609 // Parse and update CompilationInfo with the results. | 644 // Parse and update CompilationInfo with the results. |
| 610 if (!parsing::ParseAny(info->parse_info())) return MaybeHandle<Code>(); | 645 if (!parsing::ParseAny(info->parse_info())) return MaybeHandle<Code>(); |
| 611 if (info->parse_info()->is_toplevel()) { | 646 if (info->parse_info()->is_toplevel()) { |
| 612 EnsureSharedFunctionInfosArrayOnScript(info->parse_info()); | 647 EnsureSharedFunctionInfosArrayOnScript(info->parse_info()); |
| 613 } | 648 } |
| 614 DCHECK_EQ(info->shared_info()->language_mode(), | 649 DCHECK_EQ(info->shared_info()->language_mode(), |
| 615 info->literal()->language_mode()); | 650 info->literal()->language_mode()); |
| 616 | 651 |
| 617 // Compile either unoptimized code or bytecode for the interpreter. | 652 // Compile either unoptimized code or bytecode for the interpreter. |
| 618 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); | 653 if (!CompileUnoptimizedCode(info, inner_function_mode)) { |
| 654 return MaybeHandle<Code>(); | |
| 655 } | |
| 619 | 656 |
| 620 // Record the function compilation event. | 657 // Record the function compilation event. |
| 621 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); | 658 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
| 622 | 659 |
| 623 return info->code(); | 660 return info->code(); |
| 624 } | 661 } |
| 625 | 662 |
| 626 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( | 663 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( |
| 627 Handle<JSFunction> function, BailoutId osr_ast_id) { | 664 Handle<JSFunction> function, BailoutId osr_ast_id) { |
| 628 RuntimeCallTimerScope runtimeTimer( | 665 RuntimeCallTimerScope runtimeTimer( |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 918 } | 955 } |
| 919 info->closure()->ReplaceCode(shared->code()); | 956 info->closure()->ReplaceCode(shared->code()); |
| 920 return CompilationJob::FAILED; | 957 return CompilationJob::FAILED; |
| 921 } | 958 } |
| 922 | 959 |
| 923 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) { | 960 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) { |
| 924 Isolate* isolate = function->GetIsolate(); | 961 Isolate* isolate = function->GetIsolate(); |
| 925 VMState<COMPILER> state(isolate); | 962 VMState<COMPILER> state(isolate); |
| 926 PostponeInterruptsScope postpone(isolate); | 963 PostponeInterruptsScope postpone(isolate); |
| 927 ParseInfo parse_info(handle(function->shared())); | 964 ParseInfo parse_info(handle(function->shared())); |
| 928 CompilationInfo info(&parse_info, function); | 965 CompilationInfo info(parse_info.zone(), &parse_info, function); |
| 929 | 966 |
| 930 DCHECK(function->shared()->is_compiled()); | 967 DCHECK(function->shared()->is_compiled()); |
| 931 | 968 |
| 932 // Function no longer needs to be tiered up | 969 // Function no longer needs to be tiered up |
| 933 function->shared()->set_marked_for_tier_up(false); | 970 function->shared()->set_marked_for_tier_up(false); |
| 934 | 971 |
| 935 // Reset profiler ticks, function is no longer considered hot. | 972 // Reset profiler ticks, function is no longer considered hot. |
| 936 if (function->shared()->HasBytecodeArray()) { | 973 if (function->shared()->HasBytecodeArray()) { |
| 937 function->shared()->set_profiler_ticks(0); | 974 function->shared()->set_profiler_ticks(0); |
| 938 } | 975 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1051 return Handle<Code>(function->shared()->code()); | 1088 return Handle<Code>(function->shared()->code()); |
| 1052 } | 1089 } |
| 1053 | 1090 |
| 1054 if (function->shared()->HasBytecodeArray()) { | 1091 if (function->shared()->HasBytecodeArray()) { |
| 1055 Handle<Code> entry = isolate->builtins()->InterpreterEntryTrampoline(); | 1092 Handle<Code> entry = isolate->builtins()->InterpreterEntryTrampoline(); |
| 1056 function->shared()->ReplaceCode(*entry); | 1093 function->shared()->ReplaceCode(*entry); |
| 1057 return entry; | 1094 return entry; |
| 1058 } | 1095 } |
| 1059 | 1096 |
| 1060 ParseInfo parse_info(handle(function->shared())); | 1097 ParseInfo parse_info(handle(function->shared())); |
| 1061 CompilationInfo info(&parse_info, function); | 1098 Zone compile_zone(isolate->allocator(), ZONE_NAME); |
| 1099 CompilationInfo info(&compile_zone, &parse_info, function); | |
| 1062 Handle<Code> result; | 1100 Handle<Code> result; |
| 1063 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCode(&info), Code); | 1101 ASSIGN_RETURN_ON_EXCEPTION( |
| 1102 isolate, result, GetUnoptimizedCode(&info, Compiler::CONCURRENT), Code); | |
| 1064 | 1103 |
| 1065 if (FLAG_always_opt && !info.shared_info()->HasAsmWasmData()) { | 1104 if (FLAG_always_opt && !info.shared_info()->HasAsmWasmData()) { |
| 1066 Handle<Code> opt_code; | 1105 Handle<Code> opt_code; |
| 1067 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) | 1106 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) |
| 1068 .ToHandle(&opt_code)) { | 1107 .ToHandle(&opt_code)) { |
| 1069 result = opt_code; | 1108 result = opt_code; |
| 1070 } | 1109 } |
| 1071 } | 1110 } |
| 1072 | 1111 |
| 1073 return result; | 1112 return result; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1114 | 1153 |
| 1115 // Allocate a shared function info object. | 1154 // Allocate a shared function info object. |
| 1116 FunctionLiteral* lit = parse_info->literal(); | 1155 FunctionLiteral* lit = parse_info->literal(); |
| 1117 DCHECK_EQ(kNoSourcePosition, lit->function_token_position()); | 1156 DCHECK_EQ(kNoSourcePosition, lit->function_token_position()); |
| 1118 result = isolate->factory()->NewSharedFunctionInfoForLiteral(lit, script); | 1157 result = isolate->factory()->NewSharedFunctionInfoForLiteral(lit, script); |
| 1119 result->set_is_toplevel(true); | 1158 result->set_is_toplevel(true); |
| 1120 parse_info->set_shared_info(result); | 1159 parse_info->set_shared_info(result); |
| 1121 parse_info->set_function_literal_id(result->function_literal_id()); | 1160 parse_info->set_function_literal_id(result->function_literal_id()); |
| 1122 | 1161 |
| 1123 // Compile the code. | 1162 // Compile the code. |
| 1124 if (!CompileUnoptimizedCode(info)) { | 1163 if (!CompileUnoptimizedCode(info, Compiler::CONCURRENT)) { |
| 1125 return Handle<SharedFunctionInfo>::null(); | 1164 return Handle<SharedFunctionInfo>::null(); |
| 1126 } | 1165 } |
| 1127 | 1166 |
| 1128 Handle<String> script_name = | 1167 Handle<String> script_name = |
| 1129 script->name()->IsString() | 1168 script->name()->IsString() |
| 1130 ? Handle<String>(String::cast(script->name())) | 1169 ? Handle<String>(String::cast(script->name())) |
| 1131 : isolate->factory()->empty_string(); | 1170 : isolate->factory()->empty_string(); |
| 1132 CodeEventListener::LogEventsAndTags log_tag = | 1171 CodeEventListener::LogEventsAndTags log_tag = |
| 1133 parse_info->is_eval() | 1172 parse_info->is_eval() |
| 1134 ? CodeEventListener::EVAL_TAG | 1173 ? CodeEventListener::EVAL_TAG |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1223 | 1262 |
| 1224 bool Compiler::CompileOptimized(Handle<JSFunction> function, | 1263 bool Compiler::CompileOptimized(Handle<JSFunction> function, |
| 1225 ConcurrencyMode mode) { | 1264 ConcurrencyMode mode) { |
| 1226 if (function->IsOptimized()) return true; | 1265 if (function->IsOptimized()) return true; |
| 1227 Isolate* isolate = function->GetIsolate(); | 1266 Isolate* isolate = function->GetIsolate(); |
| 1228 DCHECK(AllowCompilation::IsAllowed(isolate)); | 1267 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1229 | 1268 |
| 1230 // Start a compilation. | 1269 // Start a compilation. |
| 1231 Handle<Code> code; | 1270 Handle<Code> code; |
| 1232 if (!GetOptimizedCode(function, mode).ToHandle(&code)) { | 1271 if (!GetOptimizedCode(function, mode).ToHandle(&code)) { |
| 1233 // Optimization failed, get unoptimized code. | 1272 // Optimization failed, get unoptimized code. Unoptimized code must exist |
| 1273 // already if we are optimizing. | |
| 1234 DCHECK(!isolate->has_pending_exception()); | 1274 DCHECK(!isolate->has_pending_exception()); |
| 1235 if (function->shared()->is_compiled()) { | 1275 DCHECK(function->shared()->is_compiled()); |
|
Michael Starzinger
2017/02/09 14:23:30
Nice! Glad this finally holds by now.
rmcilroy
2017/02/09 15:03:03
Acknowledged :).
| |
| 1236 code = handle(function->shared()->code(), isolate); | 1276 code = handle(function->shared()->code(), isolate); |
| 1237 } else if (function->shared()->HasBytecodeArray()) { | |
| 1238 code = isolate->builtins()->InterpreterEntryTrampoline(); | |
| 1239 function->shared()->ReplaceCode(*code); | |
| 1240 } else { | |
| 1241 ParseInfo parse_info(handle(function->shared())); | |
| 1242 CompilationInfo info(&parse_info, function); | |
| 1243 if (!GetUnoptimizedCode(&info).ToHandle(&code)) { | |
| 1244 return false; | |
| 1245 } | |
| 1246 } | |
| 1247 } | 1277 } |
| 1248 | 1278 |
| 1249 // Install code on closure. | 1279 // Install code on closure. |
| 1250 function->ReplaceCode(*code); | 1280 function->ReplaceCode(*code); |
| 1251 JSFunction::EnsureLiterals(function); | 1281 JSFunction::EnsureLiterals(function); |
| 1252 | 1282 |
| 1253 // Check postconditions on success. | 1283 // Check postconditions on success. |
| 1254 DCHECK(!isolate->has_pending_exception()); | 1284 DCHECK(!isolate->has_pending_exception()); |
| 1255 DCHECK(function->shared()->is_compiled()); | 1285 DCHECK(function->shared()->is_compiled()); |
| 1256 DCHECK(function->is_compiled()); | 1286 DCHECK(function->is_compiled()); |
| 1257 return true; | 1287 return true; |
| 1258 } | 1288 } |
| 1259 | 1289 |
| 1260 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { | 1290 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { |
| 1261 Isolate* isolate = shared->GetIsolate(); | 1291 Isolate* isolate = shared->GetIsolate(); |
| 1262 DCHECK(AllowCompilation::IsAllowed(isolate)); | 1292 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1263 | 1293 |
| 1264 // Start a compilation. | 1294 // Start a compilation. |
| 1265 ParseInfo parse_info(shared); | 1295 ParseInfo parse_info(shared); |
| 1266 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1296 CompilationInfo info(parse_info.zone(), &parse_info, |
| 1297 Handle<JSFunction>::null()); | |
| 1267 info.MarkAsDebug(); | 1298 info.MarkAsDebug(); |
| 1268 if (GetUnoptimizedCode(&info).is_null()) { | 1299 if (GetUnoptimizedCode(&info, Compiler::NOT_CONCURRENT).is_null()) { |
| 1269 isolate->clear_pending_exception(); | 1300 isolate->clear_pending_exception(); |
| 1270 return false; | 1301 return false; |
| 1271 } | 1302 } |
| 1272 | 1303 |
| 1273 // Check postconditions on success. | 1304 // Check postconditions on success. |
| 1274 DCHECK(!isolate->has_pending_exception()); | 1305 DCHECK(!isolate->has_pending_exception()); |
| 1275 DCHECK(shared->is_compiled()); | 1306 DCHECK(shared->is_compiled()); |
| 1276 DCHECK(shared->HasDebugCode()); | 1307 DCHECK(shared->HasDebugCode()); |
| 1277 return true; | 1308 return true; |
| 1278 } | 1309 } |
| 1279 | 1310 |
| 1280 MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) { | 1311 MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) { |
| 1281 Isolate* isolate = script->GetIsolate(); | 1312 Isolate* isolate = script->GetIsolate(); |
| 1282 DCHECK(AllowCompilation::IsAllowed(isolate)); | 1313 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1283 | 1314 |
| 1284 // In order to ensure that live edit function info collection finds the newly | 1315 // In order to ensure that live edit function info collection finds the newly |
| 1285 // generated shared function infos, clear the script's list temporarily | 1316 // generated shared function infos, clear the script's list temporarily |
| 1286 // and restore it at the end of this method. | 1317 // and restore it at the end of this method. |
| 1287 Handle<FixedArray> old_function_infos(script->shared_function_infos(), | 1318 Handle<FixedArray> old_function_infos(script->shared_function_infos(), |
| 1288 isolate); | 1319 isolate); |
| 1289 script->set_shared_function_infos(isolate->heap()->empty_fixed_array()); | 1320 script->set_shared_function_infos(isolate->heap()->empty_fixed_array()); |
| 1290 | 1321 |
| 1291 // Start a compilation. | 1322 // Start a compilation. |
| 1292 ParseInfo parse_info(script); | 1323 ParseInfo parse_info(script); |
| 1293 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1324 Zone compile_zone(isolate->allocator(), ZONE_NAME); |
| 1325 CompilationInfo info(&compile_zone, &parse_info, Handle<JSFunction>::null()); | |
| 1294 info.MarkAsDebug(); | 1326 info.MarkAsDebug(); |
| 1295 | 1327 |
| 1296 // TODO(635): support extensions. | 1328 // TODO(635): support extensions. |
| 1297 const bool compilation_succeeded = !CompileToplevel(&info).is_null(); | 1329 const bool compilation_succeeded = !CompileToplevel(&info).is_null(); |
| 1298 Handle<JSArray> infos; | 1330 Handle<JSArray> infos; |
| 1299 if (compilation_succeeded) { | 1331 if (compilation_succeeded) { |
| 1300 // Check postconditions on success. | 1332 // Check postconditions on success. |
| 1301 DCHECK(!isolate->has_pending_exception()); | 1333 DCHECK(!isolate->has_pending_exception()); |
| 1302 infos = LiveEditFunctionTracker::Collect(parse_info.literal(), script, | 1334 infos = LiveEditFunctionTracker::Collect(parse_info.literal(), script, |
| 1303 parse_info.zone(), isolate); | 1335 parse_info.zone(), isolate); |
| 1304 } | 1336 } |
| 1305 | 1337 |
| 1306 // Restore the original function info list in order to remain side-effect | 1338 // Restore the original function info list in order to remain side-effect |
| 1307 // free as much as possible, since some code expects the old shared function | 1339 // free as much as possible, since some code expects the old shared function |
| 1308 // infos to stick around. | 1340 // infos to stick around. |
| 1309 script->set_shared_function_infos(*old_function_infos); | 1341 script->set_shared_function_infos(*old_function_infos); |
| 1310 | 1342 |
| 1311 return infos; | 1343 return infos; |
| 1312 } | 1344 } |
| 1313 | 1345 |
| 1314 bool Compiler::EnsureBytecode(CompilationInfo* info) { | 1346 bool Compiler::EnsureBytecode(CompilationInfo* info) { |
| 1315 if (!info->shared_info()->is_compiled()) { | 1347 if (!info->shared_info()->is_compiled()) { |
| 1316 if (GetUnoptimizedCode(info).is_null()) return false; | 1348 if (GetUnoptimizedCode(info, Compiler::NOT_CONCURRENT).is_null()) { |
| 1349 return false; | |
| 1350 } | |
| 1317 } | 1351 } |
| 1318 DCHECK(info->shared_info()->is_compiled()); | 1352 DCHECK(info->shared_info()->is_compiled()); |
| 1319 | 1353 |
| 1320 if (info->shared_info()->HasAsmWasmData()) return false; | 1354 if (info->shared_info()->HasAsmWasmData()) return false; |
| 1321 | 1355 |
| 1322 DCHECK_EQ(ShouldUseIgnition(info), info->shared_info()->HasBytecodeArray()); | 1356 DCHECK_EQ(ShouldUseIgnition(info), info->shared_info()->HasBytecodeArray()); |
| 1323 return info->shared_info()->HasBytecodeArray(); | 1357 return info->shared_info()->HasBytecodeArray(); |
| 1324 } | 1358 } |
| 1325 | 1359 |
| 1326 // TODO(turbofan): In the future, unoptimized code with deopt support could | 1360 // TODO(turbofan): In the future, unoptimized code with deopt support could |
| 1327 // be generated lazily once deopt is triggered. | 1361 // be generated lazily once deopt is triggered. |
| 1328 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 1362 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
| 1329 DCHECK_NOT_NULL(info->literal()); | 1363 DCHECK_NOT_NULL(info->literal()); |
| 1330 DCHECK_NOT_NULL(info->scope()); | 1364 DCHECK_NOT_NULL(info->scope()); |
| 1331 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1365 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 1332 if (!shared->has_deoptimization_support()) { | 1366 if (!shared->has_deoptimization_support()) { |
| 1333 Zone zone(info->isolate()->allocator(), ZONE_NAME); | 1367 Zone compile_zone(info->isolate()->allocator(), ZONE_NAME); |
| 1334 CompilationInfo unoptimized(info->parse_info(), info->closure()); | 1368 CompilationInfo unoptimized(&compile_zone, info->parse_info(), |
| 1369 info->closure()); | |
| 1335 unoptimized.EnableDeoptimizationSupport(); | 1370 unoptimized.EnableDeoptimizationSupport(); |
| 1336 | 1371 |
| 1337 // Don't generate full-codegen code for functions it can't support. | 1372 // Don't generate full-codegen code for functions it can't support. |
| 1338 if (shared->must_use_ignition_turbo()) return false; | 1373 if (shared->must_use_ignition_turbo()) return false; |
| 1339 DCHECK(!IsResumableFunction(shared->kind())); | 1374 DCHECK(!IsResumableFunction(shared->kind())); |
| 1340 | 1375 |
| 1341 // When we call PrepareForSerializing below, we will change the shared | 1376 // When we call PrepareForSerializing below, we will change the shared |
| 1342 // ParseInfo. Make sure to reset it. | 1377 // ParseInfo. Make sure to reset it. |
| 1343 bool old_will_serialize_value = info->parse_info()->will_serialize(); | 1378 bool old_will_serialize_value = info->parse_info()->will_serialize(); |
| 1344 | 1379 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1424 if (!script_name.is_null()) { | 1459 if (!script_name.is_null()) { |
| 1425 script->set_name(*script_name); | 1460 script->set_name(*script_name); |
| 1426 script->set_line_offset(line_offset); | 1461 script->set_line_offset(line_offset); |
| 1427 script->set_column_offset(column_offset); | 1462 script->set_column_offset(column_offset); |
| 1428 } | 1463 } |
| 1429 script->set_origin_options(options); | 1464 script->set_origin_options(options); |
| 1430 script->set_compilation_type(Script::COMPILATION_TYPE_EVAL); | 1465 script->set_compilation_type(Script::COMPILATION_TYPE_EVAL); |
| 1431 Script::SetEvalOrigin(script, outer_info, eval_position); | 1466 Script::SetEvalOrigin(script, outer_info, eval_position); |
| 1432 | 1467 |
| 1433 ParseInfo parse_info(script); | 1468 ParseInfo parse_info(script); |
| 1434 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1469 Zone compile_zone(isolate->allocator(), ZONE_NAME); |
| 1470 CompilationInfo info(&compile_zone, &parse_info, | |
| 1471 Handle<JSFunction>::null()); | |
| 1435 parse_info.set_eval(); | 1472 parse_info.set_eval(); |
| 1436 parse_info.set_language_mode(language_mode); | 1473 parse_info.set_language_mode(language_mode); |
| 1437 parse_info.set_parse_restriction(restriction); | 1474 parse_info.set_parse_restriction(restriction); |
| 1438 if (!context->IsNativeContext()) { | 1475 if (!context->IsNativeContext()) { |
| 1439 parse_info.set_outer_scope_info(handle(context->scope_info())); | 1476 parse_info.set_outer_scope_info(handle(context->scope_info())); |
| 1440 } | 1477 } |
| 1441 | 1478 |
| 1442 shared_info = CompileToplevel(&info); | 1479 shared_info = CompileToplevel(&info); |
| 1443 if (shared_info.is_null()) { | 1480 if (shared_info.is_null()) { |
| 1444 return MaybeHandle<JSFunction>(); | 1481 return MaybeHandle<JSFunction>(); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1633 script->set_line_offset(line_offset); | 1670 script->set_line_offset(line_offset); |
| 1634 script->set_column_offset(column_offset); | 1671 script->set_column_offset(column_offset); |
| 1635 } | 1672 } |
| 1636 script->set_origin_options(resource_options); | 1673 script->set_origin_options(resource_options); |
| 1637 if (!source_map_url.is_null()) { | 1674 if (!source_map_url.is_null()) { |
| 1638 script->set_source_mapping_url(*source_map_url); | 1675 script->set_source_mapping_url(*source_map_url); |
| 1639 } | 1676 } |
| 1640 | 1677 |
| 1641 // Compile the function and add it to the cache. | 1678 // Compile the function and add it to the cache. |
| 1642 ParseInfo parse_info(script); | 1679 ParseInfo parse_info(script); |
| 1643 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1680 Zone compile_zone(isolate->allocator(), ZONE_NAME); |
| 1681 CompilationInfo info(&compile_zone, &parse_info, | |
| 1682 Handle<JSFunction>::null()); | |
| 1644 if (resource_options.IsModule()) parse_info.set_module(); | 1683 if (resource_options.IsModule()) parse_info.set_module(); |
| 1645 if (compile_options != ScriptCompiler::kNoCompileOptions) { | 1684 if (compile_options != ScriptCompiler::kNoCompileOptions) { |
| 1646 parse_info.set_cached_data(cached_data); | 1685 parse_info.set_cached_data(cached_data); |
| 1647 } | 1686 } |
| 1648 parse_info.set_compile_options(compile_options); | 1687 parse_info.set_compile_options(compile_options); |
| 1649 parse_info.set_extension(extension); | 1688 parse_info.set_extension(extension); |
| 1650 if (!context->IsNativeContext()) { | 1689 if (!context->IsNativeContext()) { |
| 1651 parse_info.set_outer_scope_info(handle(context->scope_info())); | 1690 parse_info.set_outer_scope_info(handle(context->scope_info())); |
| 1652 } | 1691 } |
| 1653 if (FLAG_serialize_toplevel && | 1692 if (FLAG_serialize_toplevel && |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1700 Handle<Script> script, ParseInfo* parse_info, int source_length) { | 1739 Handle<Script> script, ParseInfo* parse_info, int source_length) { |
| 1701 Isolate* isolate = script->GetIsolate(); | 1740 Isolate* isolate = script->GetIsolate(); |
| 1702 // TODO(titzer): increment the counters in caller. | 1741 // TODO(titzer): increment the counters in caller. |
| 1703 isolate->counters()->total_load_size()->Increment(source_length); | 1742 isolate->counters()->total_load_size()->Increment(source_length); |
| 1704 isolate->counters()->total_compile_size()->Increment(source_length); | 1743 isolate->counters()->total_compile_size()->Increment(source_length); |
| 1705 | 1744 |
| 1706 LanguageMode language_mode = construct_language_mode(FLAG_use_strict); | 1745 LanguageMode language_mode = construct_language_mode(FLAG_use_strict); |
| 1707 parse_info->set_language_mode( | 1746 parse_info->set_language_mode( |
| 1708 static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); | 1747 static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); |
| 1709 | 1748 |
| 1710 CompilationInfo compile_info(parse_info, Handle<JSFunction>::null()); | 1749 Zone compile_zone(isolate->allocator(), ZONE_NAME); |
| 1750 CompilationInfo compile_info(&compile_zone, parse_info, | |
| 1751 Handle<JSFunction>::null()); | |
| 1711 | 1752 |
| 1712 // The source was parsed lazily, so compiling for debugging is not possible. | 1753 // The source was parsed lazily, so compiling for debugging is not possible. |
| 1713 DCHECK(!compile_info.is_debug()); | 1754 DCHECK(!compile_info.is_debug()); |
| 1714 | 1755 |
| 1715 Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info); | 1756 Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info); |
| 1716 if (!result.is_null()) isolate->debug()->OnAfterCompile(script); | 1757 if (!result.is_null()) isolate->debug()->OnAfterCompile(script); |
| 1717 return result; | 1758 return result; |
| 1718 } | 1759 } |
| 1719 | 1760 |
| 1720 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( | 1761 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1829 } | 1870 } |
| 1830 | 1871 |
| 1831 if (shared->is_compiled()) { | 1872 if (shared->is_compiled()) { |
| 1832 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1873 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
| 1833 JSFunction::EnsureLiterals(function); | 1874 JSFunction::EnsureLiterals(function); |
| 1834 } | 1875 } |
| 1835 } | 1876 } |
| 1836 | 1877 |
| 1837 } // namespace internal | 1878 } // namespace internal |
| 1838 } // namespace v8 | 1879 } // namespace v8 |
| OLD | NEW |