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 20 matching lines...) Expand all Loading... | |
31 #include "src/parsing/parsing.h" | 31 #include "src/parsing/parsing.h" |
32 #include "src/parsing/rewriter.h" | 32 #include "src/parsing/rewriter.h" |
33 #include "src/parsing/scanner-character-streams.h" | 33 #include "src/parsing/scanner-character-streams.h" |
34 #include "src/runtime-profiler.h" | 34 #include "src/runtime-profiler.h" |
35 #include "src/snapshot/code-serializer.h" | 35 #include "src/snapshot/code-serializer.h" |
36 #include "src/vm-state-inl.h" | 36 #include "src/vm-state-inl.h" |
37 | 37 |
38 namespace v8 { | 38 namespace v8 { |
39 namespace internal { | 39 namespace internal { |
40 | 40 |
41 | |
42 | |
43 // A wrapper around a CompilationInfo that detaches the Handles from | 41 // A wrapper around a CompilationInfo that detaches the Handles from |
44 // the underlying DeferredHandleScope and stores them in info_ on | 42 // the underlying DeferredHandleScope and stores them in info_ on |
45 // destruction. | 43 // destruction. |
46 class CompilationHandleScope final { | 44 class CompilationHandleScope final { |
47 public: | 45 public: |
48 explicit CompilationHandleScope(CompilationInfo* info) | 46 explicit CompilationHandleScope(CompilationInfo* info) |
49 : deferred_(info->isolate()), info_(info) {} | 47 : deferred_(info->isolate()), info_(info) {} |
50 ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); } | 48 ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); } |
51 | 49 |
52 private: | 50 private: |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 // Checks whether top level functions should be passed by the filter. | 368 // Checks whether top level functions should be passed by the filter. |
371 if (shared->is_toplevel()) { | 369 if (shared->is_toplevel()) { |
372 Vector<const char> filter = CStrVector(FLAG_ignition_filter); | 370 Vector<const char> filter = CStrVector(FLAG_ignition_filter); |
373 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); | 371 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); |
374 } | 372 } |
375 | 373 |
376 // Finally respect the filter. | 374 // Finally respect the filter. |
377 return shared->PassesFilter(FLAG_ignition_filter); | 375 return shared->PassesFilter(FLAG_ignition_filter); |
378 } | 376 } |
379 | 377 |
380 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info, | 378 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { |
381 LazyCompilationMode mode) { | |
382 // Function should have been parsed and analyzed before creating a compilation | 379 // Function should have been parsed and analyzed before creating a compilation |
383 // job. | 380 // job. |
384 DCHECK_NOT_NULL(info->literal()); | 381 DCHECK_NOT_NULL(info->literal()); |
385 DCHECK_NOT_NULL(info->scope()); | 382 DCHECK_NOT_NULL(info->scope()); |
386 | 383 |
387 EnsureFeedbackMetadata(info); | 384 EnsureFeedbackMetadata(info); |
388 if (ShouldUseIgnition(info)) { | 385 if (ShouldUseIgnition(info)) { |
389 return interpreter::Interpreter::NewCompilationJob(info, mode); | 386 return interpreter::Interpreter::NewCompilationJob(info); |
390 } else { | 387 } else { |
391 return FullCodeGenerator::NewCompilationJob(info, mode); | 388 return FullCodeGenerator::NewCompilationJob(info); |
392 } | 389 } |
393 } | 390 } |
394 | 391 |
395 void InstallSharedScopeInfo(CompilationInfo* info, | 392 void InstallSharedScopeInfo(CompilationInfo* info, |
396 Handle<SharedFunctionInfo> shared) { | 393 Handle<SharedFunctionInfo> shared) { |
397 Handle<ScopeInfo> scope_info = info->scope()->scope_info(); | 394 Handle<ScopeInfo> scope_info = info->scope()->scope_info(); |
398 shared->set_scope_info(*scope_info); | 395 shared->set_scope_info(*scope_info); |
399 Scope* outer_scope = info->scope()->GetOuterScopeWithContext(); | 396 Scope* outer_scope = info->scope()->GetOuterScopeWithContext(); |
400 if (outer_scope) { | 397 if (outer_scope) { |
401 shared->set_outer_scope_info(*outer_scope->scope_info()); | 398 shared->set_outer_scope_info(*outer_scope->scope_info()); |
(...skipping 28 matching lines...) Expand all Loading... | |
430 | 427 |
431 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { | 428 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { |
432 CompilationJob::Status status = job->FinalizeJob(); | 429 CompilationJob::Status status = job->FinalizeJob(); |
433 if (status == CompilationJob::SUCCEEDED) { | 430 if (status == CompilationJob::SUCCEEDED) { |
434 InstallUnoptimizedCode(job->info()); | 431 InstallUnoptimizedCode(job->info()); |
435 job->RecordUnoptimizedCompilationStats(); | 432 job->RecordUnoptimizedCompilationStats(); |
436 } | 433 } |
437 return status; | 434 return status; |
438 } | 435 } |
439 | 436 |
437 bool Renumber(ParseInfo* parse_info) { | |
438 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), | |
439 parse_info->literal(), | |
440 parse_info->eager_inner_function_literals())) { | |
441 return false; | |
442 } | |
443 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); | |
444 if (!shared_info.is_null()) { | |
445 FunctionLiteral* lit = parse_info->literal(); | |
446 shared_info->set_ast_node_count(lit->ast_node_count()); | |
447 if (lit->dont_optimize_reason() != kNoReason) { | |
448 shared_info->DisableOptimization(lit->dont_optimize_reason()); | |
449 } | |
450 if (lit->flags() & AstProperties::kMustUseIgnitionTurbo) { | |
451 shared_info->set_must_use_ignition_turbo(true); | |
452 } | |
453 } | |
454 return true; | |
455 } | |
456 | |
440 bool GenerateUnoptimizedCode(CompilationInfo* info) { | 457 bool GenerateUnoptimizedCode(CompilationInfo* info) { |
441 if (FLAG_validate_asm && info->scope()->asm_module() && | 458 if (FLAG_validate_asm && info->scope()->asm_module() && |
442 !info->shared_info()->is_asm_wasm_broken() && !info->is_debug()) { | 459 !info->shared_info()->is_asm_wasm_broken() && !info->is_debug()) { |
443 EnsureFeedbackMetadata(info); | 460 EnsureFeedbackMetadata(info); |
444 MaybeHandle<FixedArray> wasm_data; | 461 MaybeHandle<FixedArray> wasm_data; |
445 wasm_data = AsmJs::CompileAsmViaWasm(info); | 462 wasm_data = AsmJs::CompileAsmViaWasm(info); |
446 if (!wasm_data.is_null()) { | 463 if (!wasm_data.is_null()) { |
447 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); | 464 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); |
448 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); | 465 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); |
449 InstallUnoptimizedCode(info); | 466 InstallUnoptimizedCode(info); |
450 return true; | 467 return true; |
451 } | 468 } |
452 } | 469 } |
453 | 470 |
454 std::unique_ptr<CompilationJob> job( | 471 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); |
455 GetUnoptimizedCompilationJob(info, LazyCompilationMode::kIfRequested)); | |
456 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; | 472 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; |
457 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; | 473 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; |
458 if (FinalizeUnoptimizedCompilationJob(job.get()) != | 474 if (FinalizeUnoptimizedCompilationJob(job.get()) != |
459 CompilationJob::SUCCEEDED) { | 475 CompilationJob::SUCCEEDED) { |
460 return false; | 476 return false; |
461 } | 477 } |
462 return true; | 478 return true; |
463 } | 479 } |
464 | 480 |
481 bool CompileUnoptimizedInnerFunctionsRecursively( | |
482 ZoneVector<FunctionLiteral*>* literals, CompilationInfo* outer_info) { | |
483 Isolate* isolate = outer_info->isolate(); | |
484 Handle<Script> script = outer_info->script(); | |
485 | |
486 for (auto it = literals->begin(); it != literals->end(); it++) { | |
487 FunctionLiteral* literal = *it; | |
488 | |
489 // Find any previously allocated shared function info for the given literal. | |
490 Handle<SharedFunctionInfo> shared; | |
491 MaybeHandle<SharedFunctionInfo> maybe_existing = | |
492 script->FindSharedFunctionInfo(isolate, literal); | |
493 if (maybe_existing.ToHandle(&shared)) { | |
494 DCHECK(!shared->is_toplevel()); | |
495 // If we found an existing shared function info with compiled code, | |
496 // we are done. | |
497 if (shared->is_compiled()) continue; | |
498 } else { | |
499 shared = | |
500 isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script); | |
501 shared->set_is_toplevel(false); | |
502 } | |
503 | |
504 Zone zone(isolate->allocator(), ZONE_NAME); | |
505 ParseInfo parse_info(&zone, script); | |
marja
2017/01/05 19:25:22
It's weird | surprising that we need to create a n
rmcilroy
2017/01/06 17:08:14
Yes I agree this is a bit weird (it is a copy of t
| |
506 parse_info.set_literal(literal); | |
507 parse_info.set_shared_info(shared); | |
508 parse_info.set_function_literal_id(shared->function_literal_id()); | |
509 parse_info.set_language_mode(literal->scope()->language_mode()); | |
510 parse_info.set_ast_value_factory( | |
511 outer_info->parse_info()->ast_value_factory()); | |
512 parse_info.set_ast_value_factory_owned(false); | |
513 | |
514 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | |
515 if (outer_info->will_serialize()) info.PrepareForSerializing(); | |
516 if (outer_info->is_debug()) info.MarkAsDebug(); | |
517 | |
518 if (!Renumber(&parse_info) || | |
519 !CompileUnoptimizedInnerFunctionsRecursively( | |
520 parse_info.eager_inner_function_literals(), &info) || | |
521 !GenerateUnoptimizedCode(&info)) { | |
522 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | |
523 return false; | |
524 } | |
525 | |
526 DCHECK(!info.code().is_null()); | |
527 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info); | |
528 if (literal->should_be_used_once_hint()) { | |
529 info.code()->MarkToBeExecutedOnce(isolate); | |
530 } | |
531 } | |
532 return true; | |
533 } | |
534 | |
465 bool CompileUnoptimizedCode(CompilationInfo* info) { | 535 bool CompileUnoptimizedCode(CompilationInfo* info) { |
466 DCHECK(AllowCompilation::IsAllowed(info->isolate())); | 536 Isolate* isolate = info->isolate(); |
537 DCHECK(AllowCompilation::IsAllowed(isolate)); | |
538 | |
467 if (!Compiler::Analyze(info->parse_info()) || | 539 if (!Compiler::Analyze(info->parse_info()) || |
540 !CompileUnoptimizedInnerFunctionsRecursively( | |
541 info->parse_info()->eager_inner_function_literals(), info) || | |
468 !GenerateUnoptimizedCode(info)) { | 542 !GenerateUnoptimizedCode(info)) { |
469 Isolate* isolate = info->isolate(); | |
470 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 543 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
471 return false; | 544 return false; |
472 } | 545 } |
546 | |
473 return true; | 547 return true; |
474 } | 548 } |
475 | 549 |
476 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { | 550 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { |
477 DCHECK(info->is_toplevel()); | 551 DCHECK(info->is_toplevel()); |
478 DCHECK(!info->script().is_null()); | 552 DCHECK(!info->script().is_null()); |
479 if (info->script()->shared_function_infos()->length() > 0) { | 553 if (info->script()->shared_function_infos()->length() > 0) { |
480 DCHECK_EQ(info->script()->shared_function_infos()->length(), | 554 DCHECK_EQ(info->script()->shared_function_infos()->length(), |
481 info->max_function_literal_id() + 1); | 555 info->max_function_literal_id() + 1); |
482 return; | 556 return; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 | 619 |
546 // Cache optimized context-specific code. | 620 // Cache optimized context-specific code. |
547 Handle<JSFunction> function = info->closure(); | 621 Handle<JSFunction> function = info->closure(); |
548 Handle<SharedFunctionInfo> shared(function->shared()); | 622 Handle<SharedFunctionInfo> shared(function->shared()); |
549 Handle<LiteralsArray> literals(function->literals()); | 623 Handle<LiteralsArray> literals(function->literals()); |
550 Handle<Context> native_context(function->context()->native_context()); | 624 Handle<Context> native_context(function->context()->native_context()); |
551 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | 625 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, |
552 literals, info->osr_ast_id()); | 626 literals, info->osr_ast_id()); |
553 } | 627 } |
554 | 628 |
555 bool Renumber(ParseInfo* parse_info) { | |
556 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), | |
557 parse_info->literal())) { | |
558 return false; | |
559 } | |
560 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); | |
561 if (!shared_info.is_null()) { | |
562 FunctionLiteral* lit = parse_info->literal(); | |
563 shared_info->set_ast_node_count(lit->ast_node_count()); | |
564 if (lit->dont_optimize_reason() != kNoReason) { | |
565 shared_info->DisableOptimization(lit->dont_optimize_reason()); | |
566 } | |
567 if (lit->flags() & AstProperties::kMustUseIgnitionTurbo) { | |
568 shared_info->set_must_use_ignition_turbo(true); | |
569 } | |
570 } | |
571 return true; | |
572 } | |
573 | |
574 bool GetOptimizedCodeNow(CompilationJob* job) { | 629 bool GetOptimizedCodeNow(CompilationJob* job) { |
575 CompilationInfo* info = job->info(); | 630 CompilationInfo* info = job->info(); |
576 Isolate* isolate = info->isolate(); | 631 Isolate* isolate = info->isolate(); |
577 | 632 |
578 // Parsing is not required when optimizing from existing bytecode. | 633 // Parsing is not required when optimizing from existing bytecode. |
579 if (!info->is_optimizing_from_bytecode()) { | 634 if (!info->is_optimizing_from_bytecode()) { |
580 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; | 635 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
581 EnsureFeedbackMetadata(info); | 636 EnsureFeedbackMetadata(info); |
582 } | 637 } |
583 | 638 |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1001 Handle<SharedFunctionInfo> result; | 1056 Handle<SharedFunctionInfo> result; |
1002 | 1057 |
1003 { VMState<COMPILER> state(info->isolate()); | 1058 { VMState<COMPILER> state(info->isolate()); |
1004 if (parse_info->literal() == nullptr && | 1059 if (parse_info->literal() == nullptr && |
1005 !parsing::ParseProgram(parse_info)) { | 1060 !parsing::ParseProgram(parse_info)) { |
1006 return Handle<SharedFunctionInfo>::null(); | 1061 return Handle<SharedFunctionInfo>::null(); |
1007 } | 1062 } |
1008 | 1063 |
1009 EnsureSharedFunctionInfosArrayOnScript(parse_info); | 1064 EnsureSharedFunctionInfosArrayOnScript(parse_info); |
1010 | 1065 |
1011 FunctionLiteral* lit = parse_info->literal(); | |
1012 | |
1013 // Measure how long it takes to do the compilation; only take the | 1066 // Measure how long it takes to do the compilation; only take the |
1014 // rest of the function into account to avoid overlap with the | 1067 // rest of the function into account to avoid overlap with the |
1015 // parsing statistics. | 1068 // parsing statistics. |
1016 RuntimeCallTimerScope runtimeTimer( | 1069 RuntimeCallTimerScope runtimeTimer( |
1017 isolate, parse_info->is_eval() ? &RuntimeCallStats::CompileEval | 1070 isolate, parse_info->is_eval() ? &RuntimeCallStats::CompileEval |
1018 : &RuntimeCallStats::Compile); | 1071 : &RuntimeCallStats::Compile); |
1019 HistogramTimer* rate = parse_info->is_eval() | 1072 HistogramTimer* rate = parse_info->is_eval() |
1020 ? info->isolate()->counters()->compile_eval() | 1073 ? info->isolate()->counters()->compile_eval() |
1021 : info->isolate()->counters()->compile(); | 1074 : info->isolate()->counters()->compile(); |
1022 HistogramTimerScope timer(rate); | 1075 HistogramTimerScope timer(rate); |
1023 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), | 1076 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), |
1024 parse_info->is_eval() ? "V8.CompileEval" : "V8.Compile"); | 1077 parse_info->is_eval() ? "V8.CompileEval" : "V8.Compile"); |
1025 | 1078 |
1026 // Allocate a shared function info object. | 1079 // Allocate a shared function info object. |
1080 FunctionLiteral* lit = parse_info->literal(); | |
1027 DCHECK_EQ(kNoSourcePosition, lit->function_token_position()); | 1081 DCHECK_EQ(kNoSourcePosition, lit->function_token_position()); |
1028 result = isolate->factory()->NewSharedFunctionInfoForLiteral(lit, script); | 1082 result = isolate->factory()->NewSharedFunctionInfoForLiteral(lit, script); |
1029 result->set_is_toplevel(true); | 1083 result->set_is_toplevel(true); |
1030 parse_info->set_shared_info(result); | 1084 parse_info->set_shared_info(result); |
1031 parse_info->set_function_literal_id(result->function_literal_id()); | 1085 parse_info->set_function_literal_id(result->function_literal_id()); |
1032 | 1086 |
1033 // Compile the code. | 1087 // Compile the code. |
1034 if (!CompileUnoptimizedCode(info)) { | 1088 if (!CompileUnoptimizedCode(info)) { |
1035 return Handle<SharedFunctionInfo>::null(); | 1089 return Handle<SharedFunctionInfo>::null(); |
1036 } | 1090 } |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1580 // The source was parsed lazily, so compiling for debugging is not possible. | 1634 // The source was parsed lazily, so compiling for debugging is not possible. |
1581 DCHECK(!compile_info.is_debug()); | 1635 DCHECK(!compile_info.is_debug()); |
1582 | 1636 |
1583 Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info); | 1637 Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info); |
1584 if (!result.is_null()) isolate->debug()->OnAfterCompile(script); | 1638 if (!result.is_null()) isolate->debug()->OnAfterCompile(script); |
1585 return result; | 1639 return result; |
1586 } | 1640 } |
1587 | 1641 |
1588 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( | 1642 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( |
1589 FunctionLiteral* literal, Handle<Script> script, | 1643 FunctionLiteral* literal, Handle<Script> script, |
1590 CompilationInfo* outer_info, LazyCompilationMode mode) { | 1644 CompilationInfo* outer_info) { |
1591 // Precondition: code has been parsed and scopes have been analyzed. | 1645 // Precondition: code has been parsed and scopes have been analyzed. |
1592 Isolate* isolate = outer_info->isolate(); | 1646 Isolate* isolate = outer_info->isolate(); |
1593 MaybeHandle<SharedFunctionInfo> maybe_existing; | 1647 MaybeHandle<SharedFunctionInfo> maybe_existing; |
1594 | 1648 |
1595 // Find any previously allocated shared function info for the given literal. | 1649 // Find any previously allocated shared function info for the given literal. |
1596 maybe_existing = script->FindSharedFunctionInfo(isolate, literal); | 1650 maybe_existing = script->FindSharedFunctionInfo(isolate, literal); |
1597 | 1651 |
1598 // We found an existing shared function info. If it has any sort of code | 1652 // If we found an existing shared function info, return it. |
1599 // attached, don't worry about compiling and simply return it. Otherwise, | |
1600 // continue to decide whether to eagerly compile. | |
1601 // Note that we also carry on if we are compiling eager to obtain code for | |
1602 // debugging, unless we already have code with debug break slots. | |
1603 Handle<SharedFunctionInfo> existing; | 1653 Handle<SharedFunctionInfo> existing; |
1604 if (maybe_existing.ToHandle(&existing)) { | 1654 if (maybe_existing.ToHandle(&existing)) { |
1605 DCHECK(!existing->is_toplevel()); | 1655 DCHECK(!existing->is_toplevel()); |
1606 if (existing->HasBaselineCode() || existing->HasBytecodeArray()) { | 1656 return existing; |
jochen (gone - plz use gerrit)
2017/01/05 15:53:12
this might be wrong if we want debug code, but the
rmcilroy
2017/01/05 16:02:42
The debug code logic didn't do anything any longer
| |
1607 if (!outer_info->is_debug() || existing->HasDebugCode()) { | |
1608 return existing; | |
1609 } | |
1610 } | |
1611 } | 1657 } |
1612 | 1658 |
1613 // Allocate a shared function info object. | 1659 // Allocate a shared function info object which will be compiled lazily. |
1614 Handle<SharedFunctionInfo> result; | 1660 Handle<SharedFunctionInfo> result = |
1615 if (!maybe_existing.ToHandle(&result)) { | 1661 isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script); |
jochen (gone - plz use gerrit)
2017/01/05 15:53:12
why don't you need to put the compile lazy builtin
rmcilroy
2017/01/05 16:02:42
I was confused by this too, but NewSharedFunctionI
| |
1616 result = | 1662 result->set_is_toplevel(false); |
1617 isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script); | 1663 Scope* outer_scope = literal->scope()->GetOuterScopeWithContext(); |
1618 result->set_is_toplevel(false); | 1664 if (outer_scope) { |
1665 result->set_outer_scope_info(*outer_scope->scope_info()); | |
1619 } | 1666 } |
1620 | |
1621 Zone zone(isolate->allocator(), ZONE_NAME); | |
1622 ParseInfo parse_info(&zone, script); | |
1623 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | |
1624 parse_info.set_literal(literal); | |
1625 parse_info.set_shared_info(result); | |
1626 parse_info.set_function_literal_id(result->function_literal_id()); | |
1627 parse_info.set_language_mode(literal->scope()->language_mode()); | |
1628 parse_info.set_ast_value_factory( | |
1629 outer_info->parse_info()->ast_value_factory()); | |
1630 parse_info.set_ast_value_factory_owned(false); | |
1631 | |
1632 if (outer_info->will_serialize()) info.PrepareForSerializing(); | |
1633 if (outer_info->is_debug()) info.MarkAsDebug(); | |
1634 | |
1635 // If this inner function is already compiled, we don't need to compile | |
1636 // again. When compiling for debug, we are not interested in having debug | |
1637 // break slots in inner functions, neither for setting break points nor | |
1638 // for revealing inner functions. | |
1639 // This is especially important for generators. We must not replace the | |
1640 // code for generators, as there may be suspended generator objects. | |
1641 if (!result->is_compiled()) { | |
1642 if (mode == LazyCompilationMode::kAlways || | |
1643 !literal->ShouldEagerCompile()) { | |
1644 info.SetCode(isolate->builtins()->CompileLazy()); | |
1645 Scope* outer_scope = literal->scope()->GetOuterScopeWithContext(); | |
1646 if (outer_scope) { | |
1647 result->set_outer_scope_info(*outer_scope->scope_info()); | |
1648 } | |
1649 } else { | |
1650 // Generate code | |
1651 TimerEventScope<TimerEventCompileCode> timer(isolate); | |
1652 RuntimeCallTimerScope runtimeTimer(isolate, | |
1653 &RuntimeCallStats::CompileCode); | |
1654 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode"); | |
1655 if (Renumber(info.parse_info()) && GenerateUnoptimizedCode(&info)) { | |
1656 // Code generation will ensure that the feedback vector is present and | |
1657 // appropriately sized. | |
1658 DCHECK(!info.code().is_null()); | |
1659 if (literal->should_be_used_once_hint()) { | |
1660 info.code()->MarkToBeExecutedOnce(isolate); | |
1661 } | |
1662 } else { | |
1663 return Handle<SharedFunctionInfo>::null(); | |
1664 } | |
1665 } | |
1666 } | |
1667 | |
1668 if (maybe_existing.is_null()) { | |
1669 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info); | |
1670 } | |
1671 | |
1672 return result; | 1667 return result; |
1673 } | 1668 } |
1674 | 1669 |
1675 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( | 1670 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( |
1676 v8::Extension* extension, Handle<String> name) { | 1671 v8::Extension* extension, Handle<String> name) { |
1677 Isolate* isolate = name->GetIsolate(); | 1672 Isolate* isolate = name->GetIsolate(); |
1678 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); | 1673 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); |
1679 | 1674 |
1680 // Compute the function template for the native function. | 1675 // Compute the function template for the native function. |
1681 v8::Local<v8::FunctionTemplate> fun_template = | 1676 v8::Local<v8::FunctionTemplate> fun_template = |
(...skipping 24 matching lines...) Expand all Loading... | |
1706 | 1701 |
1707 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, | 1702 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, |
1708 BailoutId osr_ast_id, | 1703 BailoutId osr_ast_id, |
1709 JavaScriptFrame* osr_frame) { | 1704 JavaScriptFrame* osr_frame) { |
1710 DCHECK(!osr_ast_id.IsNone()); | 1705 DCHECK(!osr_ast_id.IsNone()); |
1711 DCHECK_NOT_NULL(osr_frame); | 1706 DCHECK_NOT_NULL(osr_frame); |
1712 return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame); | 1707 return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame); |
1713 } | 1708 } |
1714 | 1709 |
1715 CompilationJob* Compiler::PrepareUnoptimizedCompilationJob( | 1710 CompilationJob* Compiler::PrepareUnoptimizedCompilationJob( |
1716 CompilationInfo* info, LazyCompilationMode mode) { | 1711 CompilationInfo* info) { |
1717 VMState<COMPILER> state(info->isolate()); | 1712 VMState<COMPILER> state(info->isolate()); |
1718 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info, mode)); | 1713 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); |
1719 if (job->PrepareJob() != CompilationJob::SUCCEEDED) { | 1714 if (job->PrepareJob() != CompilationJob::SUCCEEDED) { |
1720 return nullptr; | 1715 return nullptr; |
1721 } | 1716 } |
1722 return job.release(); | 1717 return job.release(); |
1723 } | 1718 } |
1724 | 1719 |
1725 bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { | 1720 bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { |
1726 // Take ownership of compilation job. Deleting job also tears down the zone. | 1721 // Take ownership of compilation job. Deleting job also tears down the zone. |
1727 std::unique_ptr<CompilationJob> job(raw_job); | 1722 std::unique_ptr<CompilationJob> job(raw_job); |
1728 | 1723 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1764 DCHECK(shared->is_compiled()); | 1759 DCHECK(shared->is_compiled()); |
1765 function->set_literals(cached.literals); | 1760 function->set_literals(cached.literals); |
1766 } else if (shared->is_compiled()) { | 1761 } else if (shared->is_compiled()) { |
1767 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1762 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
1768 JSFunction::EnsureLiterals(function); | 1763 JSFunction::EnsureLiterals(function); |
1769 } | 1764 } |
1770 } | 1765 } |
1771 | 1766 |
1772 } // namespace internal | 1767 } // namespace internal |
1773 } // namespace v8 | 1768 } // namespace v8 |
OLD | NEW |