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" |
| 11 #include "src/asmjs/asm-typer.h" | 11 #include "src/asmjs/asm-typer.h" |
| 12 #include "src/ast/ast-numbering.h" | 12 #include "src/ast/ast-numbering.h" |
| 13 #include "src/ast/prettyprinter.h" | 13 #include "src/ast/prettyprinter.h" |
| 14 #include "src/ast/scopes.h" | 14 #include "src/ast/scopes.h" |
| 15 #include "src/bootstrapper.h" | 15 #include "src/bootstrapper.h" |
| 16 #include "src/codegen.h" | 16 #include "src/codegen.h" |
| 17 #include "src/compilation-cache.h" | 17 #include "src/compilation-cache.h" |
| 18 #include "src/compiler-dispatcher/compiler-dispatcher.h" | |
| 18 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" | 19 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" |
| 19 #include "src/compiler/pipeline.h" | 20 #include "src/compiler/pipeline.h" |
| 20 #include "src/crankshaft/hydrogen.h" | 21 #include "src/crankshaft/hydrogen.h" |
| 21 #include "src/debug/debug.h" | 22 #include "src/debug/debug.h" |
| 22 #include "src/debug/liveedit.h" | 23 #include "src/debug/liveedit.h" |
| 23 #include "src/frames-inl.h" | 24 #include "src/frames-inl.h" |
| 24 #include "src/full-codegen/full-codegen.h" | 25 #include "src/full-codegen/full-codegen.h" |
| 25 #include "src/globals.h" | 26 #include "src/globals.h" |
| 26 #include "src/heap/heap.h" | 27 #include "src/heap/heap.h" |
| 27 #include "src/interpreter/interpreter.h" | 28 #include "src/interpreter/interpreter.h" |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 368 // Checks whether top level functions should be passed by the filter. | 369 // Checks whether top level functions should be passed by the filter. |
| 369 if (shared->is_toplevel()) { | 370 if (shared->is_toplevel()) { |
| 370 Vector<const char> filter = CStrVector(FLAG_ignition_filter); | 371 Vector<const char> filter = CStrVector(FLAG_ignition_filter); |
| 371 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); | 372 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); |
| 372 } | 373 } |
| 373 | 374 |
| 374 // Finally respect the filter. | 375 // Finally respect the filter. |
| 375 return shared->PassesFilter(FLAG_ignition_filter); | 376 return shared->PassesFilter(FLAG_ignition_filter); |
| 376 } | 377 } |
| 377 | 378 |
| 379 bool UseAsmWasm(CompilationInfo* info) { | |
| 380 return FLAG_validate_asm && info->scope()->asm_module() && | |
| 381 !info->shared_info()->is_asm_wasm_broken() && !info->is_debug(); | |
| 382 } | |
| 383 | |
| 378 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { | 384 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { |
| 379 // Function should have been parsed and analyzed before creating a compilation | 385 // Function should have been parsed and analyzed before creating a compilation |
| 380 // job. | 386 // job. |
| 381 DCHECK_NOT_NULL(info->literal()); | 387 DCHECK_NOT_NULL(info->literal()); |
| 382 DCHECK_NOT_NULL(info->scope()); | 388 DCHECK_NOT_NULL(info->scope()); |
| 383 | 389 |
| 384 EnsureFeedbackMetadata(info); | 390 EnsureFeedbackMetadata(info); |
| 385 if (ShouldUseIgnition(info)) { | 391 if (ShouldUseIgnition(info)) { |
| 386 return interpreter::Interpreter::NewCompilationJob(info); | 392 return interpreter::Interpreter::NewCompilationJob(info); |
| 387 } else { | 393 } else { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 // Update the shared function info with the scope info. | 427 // Update the shared function info with the scope info. |
| 422 InstallSharedScopeInfo(info, shared); | 428 InstallSharedScopeInfo(info, shared); |
| 423 | 429 |
| 424 // Install compilation result on the shared function info | 430 // Install compilation result on the shared function info |
| 425 InstallSharedCompilationResult(info, shared); | 431 InstallSharedCompilationResult(info, shared); |
| 426 } | 432 } |
| 427 | 433 |
| 428 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { | 434 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { |
| 429 CompilationJob::Status status = job->FinalizeJob(); | 435 CompilationJob::Status status = job->FinalizeJob(); |
| 430 if (status == CompilationJob::SUCCEEDED) { | 436 if (status == CompilationJob::SUCCEEDED) { |
| 431 InstallUnoptimizedCode(job->info()); | 437 CompilationInfo* info = job->info(); |
|
marja
2017/01/10 09:58:54
I'm confused; why is this kind of change needed in
rmcilroy
2017/01/12 12:31:55
The reason is that the MarkToBeExecutedOnce used t
| |
| 438 DCHECK(!info->code().is_null()); | |
| 439 if (info->parse_info()->literal()->should_be_used_once_hint()) { | |
| 440 info->code()->MarkToBeExecutedOnce(info->isolate()); | |
| 441 } | |
| 442 InstallUnoptimizedCode(info); | |
| 432 job->RecordUnoptimizedCompilationStats(); | 443 job->RecordUnoptimizedCompilationStats(); |
| 433 } | 444 } |
| 434 return status; | 445 return status; |
| 435 } | 446 } |
| 436 | 447 |
| 437 bool Renumber(ParseInfo* parse_info) { | 448 bool Renumber(ParseInfo* parse_info) { |
| 438 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), | 449 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), |
| 439 parse_info->literal(), | 450 parse_info->literal(), |
| 440 parse_info->eager_inner_function_literals())) { | 451 parse_info->eager_inner_function_literals())) { |
| 441 return false; | 452 return false; |
| 442 } | 453 } |
| 443 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); | 454 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); |
| 444 if (!shared_info.is_null()) { | 455 if (!shared_info.is_null()) { |
| 445 FunctionLiteral* lit = parse_info->literal(); | 456 FunctionLiteral* lit = parse_info->literal(); |
| 446 shared_info->set_ast_node_count(lit->ast_node_count()); | 457 shared_info->set_ast_node_count(lit->ast_node_count()); |
| 447 if (lit->dont_optimize_reason() != kNoReason) { | 458 if (lit->dont_optimize_reason() != kNoReason) { |
| 448 shared_info->DisableOptimization(lit->dont_optimize_reason()); | 459 shared_info->DisableOptimization(lit->dont_optimize_reason()); |
| 449 } | 460 } |
| 450 if (lit->flags() & AstProperties::kMustUseIgnitionTurbo) { | 461 if (lit->flags() & AstProperties::kMustUseIgnitionTurbo) { |
| 451 shared_info->set_must_use_ignition_turbo(true); | 462 shared_info->set_must_use_ignition_turbo(true); |
| 452 } | 463 } |
| 453 } | 464 } |
| 454 return true; | 465 return true; |
| 455 } | 466 } |
| 456 | 467 |
| 457 bool GenerateUnoptimizedCode(CompilationInfo* info) { | 468 bool GenerateUnoptimizedCode(CompilationInfo* info) { |
| 458 if (FLAG_validate_asm && info->scope()->asm_module() && | 469 if (UseAsmWasm(info)) { |
| 459 !info->shared_info()->is_asm_wasm_broken() && !info->is_debug()) { | |
| 460 EnsureFeedbackMetadata(info); | 470 EnsureFeedbackMetadata(info); |
| 461 MaybeHandle<FixedArray> wasm_data; | 471 MaybeHandle<FixedArray> wasm_data; |
| 462 wasm_data = AsmJs::CompileAsmViaWasm(info); | 472 wasm_data = AsmJs::CompileAsmViaWasm(info); |
| 463 if (!wasm_data.is_null()) { | 473 if (!wasm_data.is_null()) { |
| 464 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); | 474 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); |
| 465 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); | 475 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); |
| 466 InstallUnoptimizedCode(info); | 476 InstallUnoptimizedCode(info); |
| 467 return true; | 477 return true; |
| 468 } | 478 } |
| 469 } | 479 } |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 492 script->FindSharedFunctionInfo(isolate, literal); | 502 script->FindSharedFunctionInfo(isolate, literal); |
| 493 if (maybe_existing.ToHandle(&shared)) { | 503 if (maybe_existing.ToHandle(&shared)) { |
| 494 DCHECK(!shared->is_toplevel()); | 504 DCHECK(!shared->is_toplevel()); |
| 495 // If we found an existing shared function info with compiled code, | 505 // If we found an existing shared function info with compiled code, |
| 496 // we are done. | 506 // we are done. |
| 497 if (shared->is_compiled()) continue; | 507 if (shared->is_compiled()) continue; |
| 498 } else { | 508 } else { |
| 499 shared = | 509 shared = |
| 500 isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script); | 510 isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script); |
| 501 shared->set_is_toplevel(false); | 511 shared->set_is_toplevel(false); |
| 512 Scope* outer_scope = literal->scope()->GetOuterScopeWithContext(); | |
| 513 if (outer_scope) { | |
| 514 shared->set_outer_scope_info(*outer_scope->scope_info()); | |
| 515 } | |
| 502 } | 516 } |
| 503 | 517 |
| 504 Zone zone(isolate->allocator(), ZONE_NAME); | 518 std::unique_ptr<Zone> zone(new Zone(isolate->allocator(), ZONE_NAME)); |
| 505 ParseInfo parse_info(&zone, script); | 519 std::unique_ptr<ParseInfo> parse_info(new ParseInfo(zone.get(), script)); |
| 506 parse_info.set_literal(literal); | 520 std::unique_ptr<CompilationInfo> info( |
| 507 parse_info.set_shared_info(shared); | 521 new CompilationInfo(parse_info.get(), Handle<JSFunction>::null())); |
| 508 parse_info.set_function_literal_id(shared->function_literal_id()); | 522 |
| 509 parse_info.set_language_mode(literal->scope()->language_mode()); | 523 parse_info->set_literal(literal); |
| 510 parse_info.set_ast_value_factory( | 524 parse_info->set_shared_info(shared); |
| 525 parse_info->set_function_literal_id(shared->function_literal_id()); | |
| 526 parse_info->set_language_mode(literal->scope()->language_mode()); | |
| 527 parse_info->set_ast_value_factory( | |
| 511 outer_info->parse_info()->ast_value_factory()); | 528 outer_info->parse_info()->ast_value_factory()); |
| 512 parse_info.set_ast_value_factory_owned(false); | 529 parse_info->set_ast_value_factory_owned(false); |
| 513 | 530 |
| 514 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 531 if (outer_info->will_serialize()) info->PrepareForSerializing(); |
| 515 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 532 if (outer_info->is_debug()) info->MarkAsDebug(); |
| 516 if (outer_info->is_debug()) info.MarkAsDebug(); | |
| 517 | 533 |
| 518 if (!Renumber(&parse_info) || | 534 if (!Renumber(parse_info.get()) || |
| 519 !CompileUnoptimizedInnerFunctionsRecursively( | 535 !CompileUnoptimizedInnerFunctionsRecursively( |
| 520 parse_info.eager_inner_function_literals(), &info) || | 536 parse_info->eager_inner_function_literals(), info.get())) { |
| 521 !GenerateUnoptimizedCode(&info)) { | |
| 522 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 537 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
| 523 return false; | 538 return false; |
| 524 } | 539 } |
| 525 | 540 |
| 526 DCHECK(!info.code().is_null()); | 541 if (isolate->compiler_dispatcher()->IsEnabled() && |
| 527 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info); | 542 !UseAsmWasm(info.get())) { |
| 528 if (literal->should_be_used_once_hint()) { | 543 std::unique_ptr<CompilationJob> job( |
| 529 info.code()->MarkToBeExecutedOnce(isolate); | 544 Compiler::PrepareUnoptimizedCompilationJob(info.get())); |
| 545 if (!job || | |
| 546 !isolate->compiler_dispatcher()->Enqueue( | |
| 547 zone.release(), parse_info.release(), info.release(), | |
| 548 job.release())) { | |
| 549 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | |
|
marja
2017/01/10 09:58:54
This logic ("if isolate doesn't have a pending exc
rmcilroy
2017/01/12 12:31:55
I agree this is getting scattered everywhere. I've
| |
| 550 return false; | |
| 551 } | |
| 552 } else { | |
| 553 if (!GenerateUnoptimizedCode(info.get())) { | |
| 554 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | |
| 555 return false; | |
| 556 } | |
| 530 } | 557 } |
| 531 } | 558 } |
| 532 return true; | 559 return true; |
| 533 } | 560 } |
| 534 | 561 |
| 535 bool CompileUnoptimizedCode(CompilationInfo* info) { | 562 bool CompileUnoptimizedCode(CompilationInfo* info) { |
| 536 Isolate* isolate = info->isolate(); | 563 Isolate* isolate = info->isolate(); |
| 537 DCHECK(AllowCompilation::IsAllowed(isolate)); | 564 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 538 | 565 |
| 539 if (!Compiler::Analyze(info->parse_info()) || | 566 if (!Compiler::Analyze(info->parse_info()) || |
| 540 !CompileUnoptimizedInnerFunctionsRecursively( | 567 !CompileUnoptimizedInnerFunctionsRecursively( |
| 541 info->parse_info()->eager_inner_function_literals(), info) || | 568 info->parse_info()->eager_inner_function_literals(), info) || |
| 542 !GenerateUnoptimizedCode(info)) { | 569 !GenerateUnoptimizedCode(info)) { |
| 543 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 570 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
| 544 return false; | 571 return false; |
| 545 } | 572 } |
| 546 | 573 |
| 574 if (isolate->compiler_dispatcher()->IsEnabled()) { | |
| 575 // 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 | |
| 577 // the task itself. | |
| 578 isolate->compiler_dispatcher()->FinishAllNow(); | |
| 579 } | |
| 580 | |
| 547 return true; | 581 return true; |
| 548 } | 582 } |
| 549 | 583 |
| 550 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { | 584 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { |
| 551 DCHECK(info->is_toplevel()); | 585 DCHECK(info->is_toplevel()); |
| 552 DCHECK(!info->script().is_null()); | 586 DCHECK(!info->script().is_null()); |
| 553 if (info->script()->shared_function_infos()->length() > 0) { | 587 if (info->script()->shared_function_infos()->length() > 0) { |
| 554 DCHECK_EQ(info->script()->shared_function_infos()->length(), | 588 DCHECK_EQ(info->script()->shared_function_infos()->length(), |
| 555 info->max_function_literal_id() + 1); | 589 info->max_function_literal_id() + 1); |
| 556 return; | 590 return; |
| (...skipping 1202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1759 DCHECK(shared->is_compiled()); | 1793 DCHECK(shared->is_compiled()); |
| 1760 function->set_literals(cached.literals); | 1794 function->set_literals(cached.literals); |
| 1761 } else if (shared->is_compiled()) { | 1795 } else if (shared->is_compiled()) { |
| 1762 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1796 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
| 1763 JSFunction::EnsureLiterals(function); | 1797 JSFunction::EnsureLiterals(function); |
| 1764 } | 1798 } |
| 1765 } | 1799 } |
| 1766 | 1800 |
| 1767 } // namespace internal | 1801 } // namespace internal |
| 1768 } // namespace v8 | 1802 } // namespace v8 |
| OLD | NEW |