Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | Friends | List of all members
dart::kernel::KernelLoader Class Reference

#include <kernel_loader.h>

Inheritance diagram for dart::kernel::KernelLoader:
dart::ValueObject

Public Member Functions

 KernelLoader (Program *program, DirectChainedHashMap< UriToSourceTableTrait > *uri_to_source_table)
 
ObjectPtr LoadProgram (bool process_pending_classes=true)
 
void LoadLibrary (const Library &library)
 
ObjectPtr LoadExpressionEvaluationFunction (const String &library_url, const String &klass)
 
void ReadObfuscationProhibitions ()
 
void ReadLoadingUnits ()
 
- Public Member Functions inherited from dart::ValueObject
 ValueObject ()
 
 ~ValueObject ()
 

Static Public Member Functions

static ObjectLoadEntireProgram (Program *program, bool process_pending_classes=true)
 
static void FindModifiedLibraries (Program *program, IsolateGroup *isolate_group, BitVector *modified_libs, bool force_reload, bool *is_empty_program, intptr_t *p_num_classes, intptr_t *p_num_procedures)
 
static StringPtr FindSourceForScript (const uint8_t *kernel_buffer, intptr_t kernel_buffer_length, const String &url)
 
static void FinishLoading (const Class &klass)
 
static FunctionPtr GetClosureFunction (Thread *thread, intptr_t func_decl_offset, const Function &member_function, const Function &parent_function, const Object &closure_owner)
 
static void index_programs (kernel::Reader *reader, GrowableArray< intptr_t > *subprogram_file_starts)
 

Friends

class BuildingTranslationHelper
 

Detailed Description

Definition at line 172 of file kernel_loader.h.

Constructor & Destructor Documentation

◆ KernelLoader()

dart::kernel::KernelLoader::KernelLoader ( Program program,
DirectChainedHashMap< UriToSourceTableTrait > *  uri_to_source_table 
)
explicit

Member Function Documentation

◆ FindModifiedLibraries()

void dart::kernel::KernelLoader::FindModifiedLibraries ( Program program,
IsolateGroup isolate_group,
BitVector modified_libs,
bool  force_reload,
bool *  is_empty_program,
intptr_t *  p_num_classes,
intptr_t *  p_num_procedures 
)
static

Definition at line 646 of file kernel_loader.cc.

652 {
653 LongJumpScope jump;
654 Zone* zone = Thread::Current()->zone();
655 if (setjmp(*jump.Set()) == 0) {
656 if (force_reload) {
657 // If a reload is being forced we mark all libraries as having
658 // been modified.
659 const auto& libs = GrowableObjectArray::Handle(
660 isolate_group->object_store()->libraries());
661 intptr_t num_libs = libs.Length();
662 Library& lib = dart::Library::Handle(zone);
663 for (intptr_t i = 0; i < num_libs; i++) {
664 lib ^= libs.At(i);
665 if (!lib.is_dart_scheme()) {
666 modified_libs->Add(lib.index());
667 }
668 }
669 return;
670 }
671
672 if (p_num_classes != nullptr) {
673 *p_num_classes = 0;
674 }
675 if (p_num_procedures != nullptr) {
676 *p_num_procedures = 0;
677 }
678
679 // Now go through all the libraries that are present in the incremental
680 // kernel files, these will constitute the modified libraries.
681 *is_empty_program = true;
682 if (program->is_single_program()) {
683 KernelLoader loader(program, /*uri_to_source_table=*/nullptr);
684 loader.walk_incremental_kernel(modified_libs, is_empty_program,
685 p_num_classes, p_num_procedures);
686 }
687
688 GrowableArray<intptr_t> subprogram_file_starts;
689 {
690 kernel::Reader reader(program->binary());
691 index_programs(&reader, &subprogram_file_starts);
692 }
693
694 // Create "fake programs" for each sub-program.
695 intptr_t subprogram_count = subprogram_file_starts.length() - 1;
696 for (intptr_t i = 0; i < subprogram_count; ++i) {
697 intptr_t subprogram_start = subprogram_file_starts.At(i);
698 intptr_t subprogram_end = subprogram_file_starts.At(i + 1);
699 const auto& component = TypedDataBase::Handle(
700 program->binary().ViewFromTo(subprogram_start, subprogram_end));
701 Reader reader(component);
702 const char* error = nullptr;
703 std::unique_ptr<Program> subprogram = Program::ReadFrom(&reader, &error);
704 if (subprogram == nullptr) {
705 FATAL("Failed to load kernel file: %s", error);
706 }
707 ASSERT(subprogram->is_single_program());
708 KernelLoader loader(subprogram.get(), /*uri_to_source_table=*/nullptr);
709 loader.walk_incremental_kernel(modified_libs, is_empty_program,
710 p_num_classes, p_num_procedures);
711 }
712 }
713}
static Object & Handle()
Definition: object.h:407
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362
static void index_programs(kernel::Reader *reader, GrowableArray< intptr_t > *subprogram_file_starts)
KernelLoader(Program *program, DirectChainedHashMap< UriToSourceTableTrait > *uri_to_source_table)
static std::unique_ptr< Program > ReadFrom(Reader *reader, const char **error=nullptr)
#define ASSERT(E)
#define FATAL(error)
const uint8_t uint32_t uint32_t GError ** error

◆ FindSourceForScript()

StringPtr dart::kernel::KernelLoader::FindSourceForScript ( const uint8_t *  kernel_buffer,
intptr_t  kernel_buffer_length,
const String url 
)
static

Definition at line 376 of file kernel_loader.cc.

378 {
380 kExternalTypedDataUint8ArrayCid, const_cast<uint8_t*>(kernel_buffer),
381 kernel_buffer_length, Heap::kNew));
382
383 Thread* thread = Thread::Current();
384 Zone* zone = thread->zone();
385 TranslationHelper translation_helper(thread);
386 KernelReaderHelper reader(zone, &translation_helper, binary, 0);
387 intptr_t source_table_size = reader.SourceTableSize();
388 for (intptr_t i = 0; i < source_table_size; ++i) {
389 const String& source_uri = reader.SourceTableUriFor(i);
390 if (source_uri.EndsWith(uri)) {
391 return reader.GetSourceFor(i).ptr();
392 }
393 }
394 return String::null();
395}
static ExternalTypedDataPtr New(intptr_t class_id, uint8_t *data, intptr_t len, Heap::Space space=Heap::kNew, bool perform_eager_msan_initialization_check=true)
Definition: object.cc:25626
@ kNew
Definition: heap.h:38
static ObjectPtr null()
Definition: object.h:433

◆ FinishLoading()

void dart::kernel::KernelLoader::FinishLoading ( const Class klass)
static

Definition at line 1687 of file kernel_loader.cc.

1687 {
1688 ASSERT(klass.IsTopLevel() || (klass.kernel_offset() > 0));
1689
1690 Zone* zone = Thread::Current()->zone();
1691 const Library& library = Library::Handle(zone, klass.library());
1692 const Class& toplevel_class = Class::Handle(zone, library.toplevel_class());
1693 const auto& library_kernel_data =
1694 TypedDataView::Handle(zone, library.KernelLibrary());
1695 ASSERT(!library_kernel_data.IsNull());
1696
1697 const auto& kernel_info =
1698 KernelProgramInfo::Handle(zone, klass.KernelProgramInfo());
1699 const intptr_t library_kernel_offset =
1700 kernel_info.KernelLibraryStartOffset(library.kernel_library_index());
1701
1702 KernelLoader kernel_loader(kernel_info, library_kernel_data,
1703 library_kernel_offset);
1704
1705 LibraryIndex library_index(library_kernel_data);
1706
1707 if (klass.IsTopLevel()) {
1708 ASSERT(klass.ptr() == toplevel_class.ptr());
1709 kernel_loader.FinishTopLevelClassLoading(klass, library, library_index);
1710 return;
1711 }
1712
1713 const intptr_t class_offset = klass.kernel_offset();
1714 ClassIndex class_index(
1715 library_kernel_data, class_offset,
1716 // Class offsets in library index are whole program offsets.
1717 // Hence, we need to add |library_kernel_offset| to
1718 // |class_offset| to lookup the entry for the class in the library
1719 // index.
1720 library_index.SizeOfClassAtOffset(class_offset + library_kernel_offset));
1721
1722 kernel_loader.helper_.SetOffset(class_offset);
1723 ClassHelper class_helper(&kernel_loader.helper_);
1724
1725 kernel_loader.FinishClassLoading(klass, library, toplevel_class, class_offset,
1726 class_index, &class_helper);
1727}

◆ GetClosureFunction()

FunctionPtr dart::kernel::KernelLoader::GetClosureFunction ( Thread thread,
intptr_t  func_decl_offset,
const Function member_function,
const Function parent_function,
const Object closure_owner 
)
static

Definition at line 2329 of file kernel_loader.cc.

2333 {
2334 Zone* zone = thread->zone();
2335 Function& function = Function::Handle(zone);
2336 intptr_t func_node_offset = -1;
2337
2338 const auto& kernel_info =
2339 KernelProgramInfo::Handle(zone, member_function.KernelProgramInfo());
2340 const auto& library_kernel_data =
2341 TypedDataView::Handle(zone, member_function.KernelLibrary());
2342 ASSERT(!library_kernel_data.IsNull());
2343 const intptr_t library_kernel_offset = member_function.KernelLibraryOffset();
2344
2345 KernelLoader kernel_loader(kernel_info, library_kernel_data,
2346 library_kernel_offset);
2347 {
2348 // TODO(alexmarkov): Use func_decl_offset as a key in ClosureFunctionsCache
2349 // instead of func_node_offset and avoid this reading.
2350 kernel_loader.helper_.SetOffset(func_decl_offset);
2351 kernel_loader.helper_.ReadUntilFunctionNode();
2352 func_node_offset = kernel_loader.helper_.ReaderOffset();
2353
2354 {
2355 SafepointReadRwLocker ml(thread, thread->isolate_group()->program_lock());
2357 member_function, func_node_offset);
2358 if (!function.IsNull()) {
2359 return function.ptr();
2360 }
2361 }
2362 }
2363
2364 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
2366 member_function, func_node_offset);
2367 if (function.IsNull()) {
2368 ActiveClassScope active_class_scope(
2369 &kernel_loader.active_class_,
2370 &Class::Handle(zone, member_function.Owner()));
2371 ActiveMemberScope active_member(&kernel_loader.active_class_,
2372 &member_function);
2373 ActiveTypeParametersScope active_type_params(
2374 &kernel_loader.active_class_, member_function,
2375 &FunctionType::Handle(zone, parent_function.signature()), zone);
2376 kernel_loader.helper_.SetOffset(func_decl_offset);
2377 function =
2378 kernel_loader.LoadClosureFunction(parent_function, closure_owner);
2379 }
2380 return function.ptr();
2381}
static FunctionPtr LookupClosureFunctionLocked(const Function &member_function, intptr_t kernel_offset)
Dart_NativeFunction function
Definition: fuchsia.cc:51

◆ index_programs()

void dart::kernel::KernelLoader::index_programs ( kernel::Reader reader,
GrowableArray< intptr_t > *  subprogram_file_starts 
)
static

Definition at line 355 of file kernel_loader.cc.

357 {
358 // Dill files can be concatenated (e.g. cat a.dill b.dill > c.dill), so we
359 // need to first index the (possibly combined) file.
360 // First entry becomes last entry.
361 // Last entry is for ease of calculating size of last subprogram.
362 subprogram_file_starts->Add(reader->size());
363 reader->set_offset(reader->size() - 4);
364 while (reader->offset() > 0) {
365 intptr_t size = reader->ReadUInt32();
366 intptr_t start = reader->offset() - size;
367 if (start < 0) {
368 FATAL("Invalid kernel binary: Indicated size is invalid.");
369 }
370 subprogram_file_starts->Add(start);
371 reader->set_offset(start - 4);
372 }
373 subprogram_file_starts->Reverse();
374}
void Add(const T &value)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259

◆ LoadEntireProgram()

Object & dart::kernel::KernelLoader::LoadEntireProgram ( Program program,
bool  process_pending_classes = true 
)
static

Definition at line 255 of file kernel_loader.cc.

256 {
257 Thread* thread = Thread::Current();
258
259 TIMELINE_DURATION(thread, Isolate, "LoadKernel");
260
261 if (program->is_single_program()) {
262 KernelLoader loader(program, /*uri_to_source_table=*/nullptr);
263 return Object::Handle(loader.LoadProgram(process_pending_classes));
264 }
265
266 GrowableArray<intptr_t> subprogram_file_starts;
267 {
268 kernel::Reader reader(program->binary());
269 index_programs(&reader, &subprogram_file_starts);
270 }
271
272 Zone* zone = thread->zone();
273 Library& library = Library::Handle(zone);
274 intptr_t subprogram_count = subprogram_file_starts.length() - 1;
275
276 // First index all source tables.
277 UriToSourceTable uri_to_source_table;
278 UriToSourceTableEntry wrapper;
279 Thread* thread_ = Thread::Current();
280 Zone* zone_ = thread_->zone();
281 for (intptr_t i = subprogram_count - 1; i >= 0; --i) {
282 intptr_t subprogram_start = subprogram_file_starts.At(i);
283 intptr_t subprogram_end = subprogram_file_starts.At(i + 1);
284 const auto& component = TypedDataBase::Handle(
285 program->binary().ViewFromTo(subprogram_start, subprogram_end));
286 TranslationHelper translation_helper(thread);
287 KernelReaderHelper helper_(zone_, &translation_helper, component, 0);
288 const intptr_t source_table_size = helper_.SourceTableSize();
289 for (intptr_t index = 0; index < source_table_size; ++index) {
290 const String& uri_string = helper_.SourceTableUriFor(index);
291 wrapper.uri = &uri_string;
292 TypedData& line_starts =
293 TypedData::Handle(Z, helper_.GetLineStartsFor(index));
294 if (line_starts.Length() == 0) continue;
295 const String& script_source = helper_.GetSourceFor(index);
296 wrapper.uri = &uri_string;
297 UriToSourceTableEntry* pair = uri_to_source_table.LookupValue(&wrapper);
298 if (pair != nullptr) {
299 // At least two entries with content. Unless the content is the same
300 // that's not valid.
301 const bool src_differ = pair->sources->CompareTo(script_source) != 0;
302 const bool line_starts_differ =
303 !pair->line_starts->CanonicalizeEquals(line_starts);
304 if (src_differ || line_starts_differ) {
305 FATAL(
306 "Invalid kernel binary: Contains at least two source entries "
307 "that do not agree. URI '%s', difference: %s. Subprogram count: "
308 "%" Pd ".",
309 uri_string.ToCString(),
310 src_differ && line_starts_differ
311 ? "src and line starts"
312 : (src_differ ? "src" : "line starts"),
313 subprogram_count);
314 }
315 } else {
316 UriToSourceTableEntry* tmp = new UriToSourceTableEntry();
317 tmp->uri = &uri_string;
318 tmp->sources = &script_source;
319 tmp->line_starts = &line_starts;
320 uri_to_source_table.Insert(tmp);
321 }
322 }
323 }
324
325 // Create "fake programs" for each sub-program.
326 for (intptr_t i = subprogram_count - 1; i >= 0; --i) {
327 intptr_t subprogram_start = subprogram_file_starts.At(i);
328 intptr_t subprogram_end = subprogram_file_starts.At(i + 1);
329 const auto& component = TypedDataBase::Handle(
330 program->binary().ViewFromTo(subprogram_start, subprogram_end));
331 Reader reader(component);
332 const char* error = nullptr;
333 std::unique_ptr<Program> subprogram = Program::ReadFrom(&reader, &error);
334 if (subprogram == nullptr) {
335 FATAL("Failed to load kernel file: %s", error);
336 }
337 ASSERT(subprogram->is_single_program());
338 KernelLoader loader(subprogram.get(), &uri_to_source_table);
339 Object& load_result = Object::Handle(loader.LoadProgram(false));
340 if (load_result.IsError()) return load_result;
341
342 if (load_result.IsLibrary()) {
343 library ^= load_result.ptr();
344 }
345 }
346
347 if (process_pending_classes && !ClassFinalizer::ProcessPendingClasses()) {
348 // Class finalization failed -> sticky error would be set.
349 return Error::Handle(thread->StealStickyError());
350 }
351
352 return library;
353}
static bool ProcessPendingClasses()
intptr_t CompareTo(const String &other) const
Definition: object.cc:23638
const String & GetSourceFor(intptr_t index)
TypedDataPtr GetLineStartsFor(intptr_t index)
#define Z
DirectChainedHashMap< UriToSourceTableTrait > UriToSourceTable
#define Pd
Definition: globals.h:408
#define TIMELINE_DURATION(thread, stream, name)
Definition: timeline.h:39

◆ LoadExpressionEvaluationFunction()

ObjectPtr dart::kernel::KernelLoader::LoadExpressionEvaluationFunction ( const String library_url,
const String klass 
)

Definition at line 588 of file kernel_loader.cc.

590 {
591 // Find the original context, i.e. library/class, in which the evaluation will
592 // happen.
593 const Library& real_library =
594 Library::Handle(Z, Library::LookupLibrary(thread_, library_url));
595 ASSERT(!real_library.IsNull());
596 const Class& real_class = Class::Handle(
597 Z, klass.IsNull() ? real_library.toplevel_class()
598 : real_library.LookupClassAllowPrivate(klass));
599 ASSERT(!real_class.IsNull());
600
601 const intptr_t num_cids = IG->class_table()->NumCids();
602 const intptr_t num_libs =
603 GrowableObjectArray::Handle(IG->object_store()->libraries()).Length();
604
605 // Load the "evaluate:source" expression evaluation library.
606 ASSERT(expression_evaluation_library_.IsNull());
607 ASSERT(H.GetExpressionEvaluationClass().IsNull());
608 ASSERT(H.GetExpressionEvaluationFunction().IsNull());
609 H.SetExpressionEvaluationRealClass(real_class);
610 const Object& result = Object::Handle(Z, LoadProgram(true));
611 if (result.IsError()) {
612 return result.ptr();
613 }
614 const Function& function = H.GetExpressionEvaluationFunction();
615 ASSERT(!function.IsNull());
616 ASSERT(
617 GrowableObjectArray::Handle(IG->object_store()->libraries()).Length() ==
618 num_libs);
619 ASSERT(IG->class_table()->NumCids() == num_cids);
620
621 // Make the expression evaluation function have the right script,
622 // kernel data and parent.
623 const auto& eval_script = Script::Handle(Z, function.script());
624 ASSERT(!expression_evaluation_library_.IsNull());
625 function.SetKernelLibraryAndEvalScript(
626 eval_script, kernel_program_info_,
627 expression_evaluation_library_.kernel_library_index());
628
629 function.set_owner(real_class);
630
631 ASSERT(real_class.is_finalized());
632 // The owner class has already been marked as finalized so the signature of
633 // this added function must be finalized here, since finalization of member
634 // types will not be called anymore.
635 FunctionType& signature = FunctionType::Handle(Z, function.signature());
636 if (!function.is_static()) {
637 // Patch the illegal receiver type (type class with kIllegalCid) to dynamic.
638 signature.SetParameterTypeAt(0, Object::dynamic_type());
639 }
640 signature ^= ClassFinalizer::FinalizeType(signature);
641 function.SetSignature(signature);
642
643 return function.ptr();
644}
static AbstractTypePtr FinalizeType(const AbstractType &type, FinalizationKind finalization=kCanonicalize)
static LibraryPtr LookupLibrary(Thread *thread, const String &url)
Definition: object.cc:14599
intptr_t kernel_library_index() const
Definition: object.h:5309
bool IsNull() const
Definition: object.h:363
ObjectPtr LoadProgram(bool process_pending_classes=true)
GAsyncResult * result
#define IG
Definition: SkMD5.cpp:130

◆ LoadLibrary()

void dart::kernel::KernelLoader::LoadLibrary ( const Library library)

Definition at line 571 of file kernel_loader.cc.

571 {
572 // This will be invoked by VM bootstrapping code.
573 SafepointWriteRwLocker ml(thread_, thread_->isolate_group()->program_lock());
574
575 ASSERT(!library.Loaded());
576
577 const auto& uri = String::Handle(Z, library.url());
578 const intptr_t num_libraries = program_->library_count();
579 for (intptr_t i = 0; i < num_libraries; ++i) {
580 const String& library_uri = LibraryUri(i);
581 if (library_uri.Equals(uri)) {
582 LoadLibrary(i);
583 return;
584 }
585 }
586}
SafepointRwLock * program_lock()
Definition: isolate.h:537
IsolateGroup * isolate_group() const
Definition: thread.h:541
void LoadLibrary(const Library &library)
intptr_t library_count()
Definition: kernel.h:92

◆ LoadProgram()

ObjectPtr dart::kernel::KernelLoader::LoadProgram ( bool  process_pending_classes = true)

Definition at line 518 of file kernel_loader.cc.

518 {
519 SafepointWriteRwLocker ml(thread_, thread_->isolate_group()->program_lock());
520 ASSERT(kernel_program_info_.constants() == Array::null());
521
522 if (!program_->is_single_program()) {
523 FATAL(
524 "Trying to load a concatenated dill file at a time where that is "
525 "not allowed");
526 }
527
528 LongJumpScope jump;
529 if (setjmp(*jump.Set()) == 0) {
530 // Note that `problemsAsJson` on Component is implicitly skipped.
531 const intptr_t length = program_->library_count();
532 for (intptr_t i = 0; i < length; i++) {
533 LoadLibrary(i);
534 }
535
536 // Finalize still pending classes if requested.
537 if (process_pending_classes) {
539 // Class finalization failed -> sticky error would be set.
540 return H.thread()->StealStickyError();
541 }
542 }
543
544 // Sets the constants array to an empty array with the length equal to
545 // the number of constants. The array gets filled lazily while reading
546 // constants.
547 ASSERT(kernel_program_info_.constants_table() != ExternalTypedData::null());
548 ConstantReader constant_reader(&helper_, &active_class_);
549 const intptr_t num_consts = constant_reader.NumConstants();
550 const Array& array = Array::Handle(Z, Array::New(num_consts, Heap::kOld));
551 for (intptr_t i = 0; i < num_consts; i++) {
552 array.SetAt(i, Object::sentinel());
553 }
554 kernel_program_info_.set_constants(array);
555 H.SetConstants(array); // for caching
556
557 NameIndex main = program_->main_method();
558 if (main != -1) {
559 NameIndex main_library = H.EnclosingName(main);
560 return LookupLibrary(main_library);
561 }
562
563 return Library::null();
564 }
565
566 // Either class finalization failed or we caught a compile error.
567 // In both cases sticky error would be set.
569}
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition: object.h:10959
@ kOld
Definition: heap.h:39
void set_constants(const Array &constants) const
Definition: object.cc:15089
ArrayPtr constants() const
Definition: object.h:5521
TypedDataViewPtr constants_table() const
Definition: object.h:5512
DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError()
Definition: thread.cc:245
bool is_single_program()
Definition: kernel.h:79
NameIndex main_method()
Definition: kernel.h:80
size_t length
Definition: main.py:1

◆ ReadLoadingUnits()

void dart::kernel::KernelLoader::ReadLoadingUnits ( )

Definition at line 250 of file kernel_loader.cc.

250 {
251 LoadingUnitsMetadataHelper helper(&helper_);
252 helper.ReadLoadingUnits();
253}

◆ ReadObfuscationProhibitions()

void dart::kernel::KernelLoader::ReadObfuscationProhibitions ( )

Definition at line 245 of file kernel_loader.cc.

245 {
246 ObfuscationProhibitionsMetadataHelper helper(&helper_);
247 helper.ReadProhibitions();
248}

Friends And Related Function Documentation

◆ BuildingTranslationHelper

friend class BuildingTranslationHelper
friend

Definition at line 418 of file kernel_loader.h.


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