Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | List of all members
dart::CompileParsedFunctionHelper Class Reference
Inheritance diagram for dart::CompileParsedFunctionHelper:
dart::ValueObject

Public Member Functions

 CompileParsedFunctionHelper (ParsedFunction *parsed_function, bool optimized, intptr_t osr_id)
 
CodePtr Compile (CompilationPipeline *pipeline)
 
- Public Member Functions inherited from dart::ValueObject
 ValueObject ()
 
 ~ValueObject ()
 

Detailed Description

Definition at line 304 of file compiler.cc.

Constructor & Destructor Documentation

◆ CompileParsedFunctionHelper()

dart::CompileParsedFunctionHelper::CompileParsedFunctionHelper ( ParsedFunction parsed_function,
bool  optimized,
intptr_t  osr_id 
)
inline

Definition at line 306 of file compiler.cc.

309 : parsed_function_(parsed_function),
310 optimized_(optimized),
311 osr_id_(osr_id),
312 thread_(Thread::Current()) {}
static Thread * Current()
Definition thread.h:361

Member Function Documentation

◆ Compile()

CodePtr dart::CompileParsedFunctionHelper::Compile ( CompilationPipeline pipeline)

Definition at line 488 of file compiler.cc.

488 {
489 ASSERT(!FLAG_precompiled_mode);
490 const Function& function = parsed_function()->function();
491 if (optimized() && !function.IsOptimizable()) {
492 return Code::null();
493 }
494 Zone* const zone = thread()->zone();
495 HANDLESCOPE(thread());
496 EnterCompilerScope cs(thread());
497
498 // We may reattempt compilation if the function needs to be assembled using
499 // far branches on ARM. In the else branch of the setjmp call, done is set to
500 // false, and use_far_branches is set to true if there is a longjmp from the
501 // ARM assembler. In all other paths through this while loop, done is set to
502 // true. use_far_branches is always false on ia32 and x64.
503 volatile bool done = false;
504 // volatile because the variable may be clobbered by a longjmp.
505 volatile intptr_t far_branch_level = 0;
506
507 // In the JIT case we allow speculative inlining and have no need for a
508 // suppression, since we don't restart optimization.
509 SpeculativeInliningPolicy speculative_policy(/*enable_suppression=*/false);
510
511 Code* volatile result = &Code::ZoneHandle(zone);
512 while (!done) {
513 *result = Code::null();
514 LongJumpScope jump;
515 if (setjmp(*jump.Set()) == 0) {
516 FlowGraph* flow_graph = nullptr;
517 ZoneGrowableArray<const ICData*>* ic_data_array = nullptr;
518
519 CompilerState compiler_state(thread(), /*is_aot=*/false, optimized(),
521 compiler_state.set_function(function);
522
523 {
524 // Extract type feedback before the graph is built, as the graph
525 // builder uses it to attach it to nodes.
526 ic_data_array = new (zone) ZoneGrowableArray<const ICData*>();
527
528 // Clone ICData for background compilation so that it does not
529 // change while compiling.
530 const bool clone_ic_data = Compiler::IsBackgroundCompilation();
531 function.RestoreICDataMap(ic_data_array, clone_ic_data);
532
533 if (optimized()) {
534 ASSERT(function.ic_data_array() != Array::null() ||
535 function.ForceOptimize());
536 }
537
538 if (FLAG_print_ic_data_map) {
539 for (intptr_t i = 0; i < ic_data_array->length(); i++) {
540 if ((*ic_data_array)[i] != nullptr) {
541 THR_Print("%" Pd " ", i);
542 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]);
543 }
544 }
545 }
546
547 TIMELINE_DURATION(thread(), CompilerVerbose, "BuildFlowGraph");
548 flow_graph = pipeline->BuildFlowGraph(
549 zone, parsed_function(), ic_data_array, osr_id(), optimized());
550 }
551
552 const bool print_flow_graph =
553 (FLAG_print_flow_graph ||
554 (optimized() && FLAG_print_flow_graph_optimized)) &&
556
557 if (print_flow_graph && !optimized()) {
558 FlowGraphPrinter::PrintGraph("Unoptimized Compilation", flow_graph);
559 }
560
561 if (flow_graph->should_reorder_blocks()) {
562 TIMELINE_DURATION(thread(), CompilerVerbose,
563 "BlockScheduler::AssignEdgeWeights");
565 }
566
567 CompilerPassState pass_state(thread(), flow_graph, &speculative_policy);
568
569 if (optimized()) {
570 TIMELINE_DURATION(thread(), CompilerVerbose, "OptimizationPasses");
571
572 JitCallSpecializer call_specializer(flow_graph, &speculative_policy);
573 pass_state.call_specializer = &call_specializer;
574
575 flow_graph = CompilerPass::RunPipeline(CompilerPass::kJIT, &pass_state);
576 }
577
578 ASSERT(pass_state.inline_id_to_function.length() ==
579 pass_state.caller_inline_id.length());
580 compiler::ObjectPoolBuilder object_pool_builder;
581 compiler::Assembler assembler(&object_pool_builder, far_branch_level);
582 FlowGraphCompiler graph_compiler(
583 &assembler, flow_graph, *parsed_function(), optimized(),
584 &speculative_policy, pass_state.inline_id_to_function,
585 pass_state.inline_id_to_token_pos, pass_state.caller_inline_id,
586 ic_data_array);
587 pass_state.graph_compiler = &graph_compiler;
588 CompilerPass::GenerateCode(&pass_state);
589
590 {
591 TIMELINE_DURATION(thread(), CompilerVerbose, "FinalizeCompilation");
592
593 auto install_code_fun = [&]() {
594 *result =
595 FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
596#if !defined(PRODUCT)
597 // Isolate debuggers need to be notified of compiled function right
598 // away as code is installed because there might be latent breakpoints
599 // in compiled function, which have to be activated before functions
600 // code is executed. Otherwise concurrently running isolates might
601 // execute code before its patched and miss a need to pause at a
602 // breakpoint.
603 if (!result->IsNull()) {
604 if (!function.HasOptimizedCode()) {
606 function);
607 }
608 }
609#endif
610 };
611
612 // Grab write program_lock outside of potential safepoint, that lock
613 // can't be waited for inside the safepoint.
614 // Initially read lock was added to guard direct_subclasses field
615 // access.
616 // Read lock was upgraded to write lock to guard dependent code updates.
617 SafepointWriteRwLocker ml(thread(),
618 thread()->isolate_group()->program_lock());
619 // We have to ensure no mutators are running, because:
620 //
621 // a) We allocate an instructions object, which might cause us to
622 // temporarily flip page protections (RX -> RW -> RX).
623 //
624 // b) We have to ensure the code generated does not violate
625 // assumptions (e.g. CHA, field guards), the validation has to
626 // happen while mutator is stopped.
627 //
628 // b) We update the [Function] object with a new [Code] which
629 // requires updating several pointers: We have to ensure all of
630 // those writes are observed atomically.
631 //
633 install_code_fun, /*use_force_growth=*/true);
634 }
635 if (!result->IsNull()) {
636 // Must be called outside of safepoint.
638
639 if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) {
641 } else if (FLAG_disassemble_optimized && optimized() &&
644 }
645 }
646 // Exit the loop and the function with the correct result value.
647 done = true;
648 } else {
649 // We bailed out or we encountered an error.
650 const Error& error = Error::Handle(thread()->StealStickyError());
651
652 if (error.ptr() == Object::branch_offset_error().ptr()) {
653 // Compilation failed due to an out of range branch offset in the
654 // assembler. We try again (done = false) with far branches enabled.
655 done = false;
656 RELEASE_ASSERT(far_branch_level < 2);
657 far_branch_level++;
658 } else if (error.ptr() == Object::speculative_inlining_error().ptr()) {
659 // Can only happen with precompilation.
660 UNREACHABLE();
661 } else {
662 // If the error isn't due to an out of range branch offset, we don't
663 // try again (done = true).
664 if (FLAG_trace_bailout) {
665 THR_Print("%s\n", error.ToErrorCString());
666 }
667 if (!Compiler::IsBackgroundCompilation() && error.IsLanguageError() &&
668 (LanguageError::Cast(error).kind() == Report::kBailout)) {
669 // If is is not a background compilation, discard the error if it was
670 // not a real error, but just a bailout. If we're it a background
671 // compilation this will be dealt with in the caller.
672 } else {
673 // Otherwise, continue propagating unless we will try again.
674 thread()->set_sticky_error(error);
675 }
676 done = true;
677 }
678 }
679 }
680 return result->ptr();
681}
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
Definition DM.cpp:263
#define UNREACHABLE()
Definition assert.h:248
#define RELEASE_ASSERT(cond)
Definition assert.h:327
static void AssignEdgeWeights(FlowGraph *flow_graph)
static void NotifyCodeObservers(const Code &code, bool optimized)
Definition object.cc:18191
static DART_WARN_UNUSED_RESULT FlowGraph * RunPipeline(PipelineMode mode, CompilerPassState *state)
static void GenerateCode(CompilerPassState *state)
static bool ShouldTrace()
static bool IsBackgroundCompilation()
Definition compiler.cc:299
static void DisassembleCode(const Function &function, const Code &code, bool optimized)
static void PrintGraph(const char *phase, FlowGraph *flow_graph)
static bool ShouldPrint(const Function &function, uint8_t **compiler_pass_filter=nullptr)
static void PrintICData(const ICData &ic_data, intptr_t num_checks_to_print=kPrintAll)
void NotifyCompilation(const Function &func)
Definition debugger.cc:2954
GroupDebugger * debugger() const
Definition isolate.h:314
void RunWithStoppedMutators(T single_current_mutator, S otherwise, bool use_force_growth_in_otherwise=false)
Definition isolate.h:604
static ObjectPtr null()
Definition object.h:433
static Object & Handle()
Definition object.h:407
static Object & ZoneHandle()
Definition object.h:419
const Function & function() const
Definition parser.h:73
Zone * zone() const
void set_sticky_error(const Error &value)
Definition thread.cc:234
IsolateGroup * isolate_group() const
Definition thread.h:540
#define THR_Print(format,...)
Definition log.h:20
#define ASSERT(E)
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
Dart_NativeFunction function
Definition fuchsia.cc:51
#define HANDLESCOPE(thread)
Definition handles.h:321
#define Pd
Definition globals.h:408
#define TIMELINE_DURATION(thread, stream, name)
Definition timeline.h:39

The documentation for this class was generated from the following file: