Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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 627 of file kernel_loader.cc.

633 {
634 LongJumpScope jump;
635 Zone* zone = Thread::Current()->zone();
636 if (setjmp(*jump.Set()) == 0) {
637 if (force_reload) {
638 // If a reload is being forced we mark all libraries as having
639 // been modified.
640 const auto& libs = GrowableObjectArray::Handle(
641 isolate_group->object_store()->libraries());
642 intptr_t num_libs = libs.Length();
643 Library& lib = dart::Library::Handle(zone);
644 for (intptr_t i = 0; i < num_libs; i++) {
645 lib ^= libs.At(i);
646 if (!lib.is_dart_scheme()) {
647 modified_libs->Add(lib.index());
648 }
649 }
650 return;
651 }
652
653 if (p_num_classes != nullptr) {
654 *p_num_classes = 0;
655 }
656 if (p_num_procedures != nullptr) {
657 *p_num_procedures = 0;
658 }
659
660 // Now go through all the libraries that are present in the incremental
661 // kernel files, these will constitute the modified libraries.
662 *is_empty_program = true;
663 if (program->is_single_program()) {
664 KernelLoader loader(program, /*uri_to_source_table=*/nullptr);
665 loader.walk_incremental_kernel(modified_libs, is_empty_program,
666 p_num_classes, p_num_procedures);
667 }
668
669 GrowableArray<intptr_t> subprogram_file_starts;
670 {
671 kernel::Reader reader(program->binary());
672 index_programs(&reader, &subprogram_file_starts);
673 }
674
675 // Create "fake programs" for each sub-program.
676 intptr_t subprogram_count = subprogram_file_starts.length() - 1;
677 for (intptr_t i = 0; i < subprogram_count; ++i) {
678 intptr_t subprogram_start = subprogram_file_starts.At(i);
679 intptr_t subprogram_end = subprogram_file_starts.At(i + 1);
680 const auto& component = TypedDataBase::Handle(
681 program->binary().ViewFromTo(subprogram_start, subprogram_end));
682 Reader reader(component);
683 const char* error = nullptr;
684 std::unique_ptr<Program> subprogram = Program::ReadFrom(&reader, &error);
685 if (subprogram == nullptr) {
686 FATAL("Failed to load kernel file: %s", error);
687 }
688 ASSERT(subprogram->is_single_program());
689 KernelLoader loader(subprogram.get(), /*uri_to_source_table=*/nullptr);
690 loader.walk_incremental_kernel(modified_libs, is_empty_program,
691 p_num_classes, p_num_procedures);
692 }
693 }
694}
static Object & Handle()
Definition object.h:407
Zone * zone() const
static Thread * Current()
Definition thread.h:361
static void index_programs(kernel::Reader *reader, GrowableArray< intptr_t > *subprogram_file_starts)
KernelLoader(Program *program, DirectChainedHashMap< UriToSourceTableTrait > *uri_to_source_table)
#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 357 of file kernel_loader.cc.

359 {
361 kExternalTypedDataUint8ArrayCid, const_cast<uint8_t*>(kernel_buffer),
362 kernel_buffer_length, Heap::kNew));
363
364 Thread* thread = Thread::Current();
365 Zone* zone = thread->zone();
366 TranslationHelper translation_helper(thread);
367 KernelReaderHelper reader(zone, &translation_helper, binary, 0);
368 intptr_t source_table_size = reader.SourceTableSize();
369 for (intptr_t i = 0; i < source_table_size; ++i) {
370 const String& source_uri = reader.SourceTableUriFor(i);
371 if (source_uri.EndsWith(uri)) {
372 return reader.GetSourceFor(i).ptr();
373 }
374 }
375 return String::null();
376}
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:25705
@ 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 1667 of file kernel_loader.cc.

1667 {
1668 ASSERT(klass.IsTopLevel() || (klass.kernel_offset() > 0));
1669
1670 Zone* zone = Thread::Current()->zone();
1671 const Library& library = Library::Handle(zone, klass.library());
1672 const Class& toplevel_class = Class::Handle(zone, library.toplevel_class());
1673 const auto& library_kernel_data =
1674 TypedDataView::Handle(zone, library.KernelLibrary());
1675 ASSERT(!library_kernel_data.IsNull());
1676
1677 const auto& kernel_info =
1678 KernelProgramInfo::Handle(zone, klass.KernelProgramInfo());
1679 const intptr_t library_kernel_offset =
1680 kernel_info.KernelLibraryStartOffset(library.kernel_library_index());
1681
1682 KernelLoader kernel_loader(kernel_info, library_kernel_data,
1683 library_kernel_offset);
1684
1685 LibraryIndex library_index(library_kernel_data);
1686
1687 if (klass.IsTopLevel()) {
1688 ASSERT(klass.ptr() == toplevel_class.ptr());
1689 kernel_loader.FinishTopLevelClassLoading(klass, library, library_index);
1690 return;
1691 }
1692
1693 const intptr_t class_offset = klass.kernel_offset();
1694 ClassIndex class_index(
1695 library_kernel_data, class_offset,
1696 // Class offsets in library index are whole program offsets.
1697 // Hence, we need to add |library_kernel_offset| to
1698 // |class_offset| to lookup the entry for the class in the library
1699 // index.
1700 library_index.SizeOfClassAtOffset(class_offset + library_kernel_offset));
1701
1702 kernel_loader.helper_.SetOffset(class_offset);
1703 ClassHelper class_helper(&kernel_loader.helper_);
1704
1705 kernel_loader.FinishClassLoading(klass, library, toplevel_class, class_offset,
1706 class_index, &class_helper);
1707}

◆ 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 2290 of file kernel_loader.cc.

2294 {
2295 Zone* zone = thread->zone();
2296 Function& function = Function::Handle(zone);
2297 intptr_t func_node_offset = -1;
2298
2299 const auto& kernel_info =
2300 KernelProgramInfo::Handle(zone, member_function.KernelProgramInfo());
2301 const auto& library_kernel_data =
2302 TypedDataView::Handle(zone, member_function.KernelLibrary());
2303 ASSERT(!library_kernel_data.IsNull());
2304 const intptr_t library_kernel_offset = member_function.KernelLibraryOffset();
2305
2306 KernelLoader kernel_loader(kernel_info, library_kernel_data,
2307 library_kernel_offset);
2308 {
2309 // TODO(alexmarkov): Use func_decl_offset as a key in ClosureFunctionsCache
2310 // instead of func_node_offset and avoid this reading.
2311 kernel_loader.helper_.SetOffset(func_decl_offset);
2312 kernel_loader.helper_.ReadUntilFunctionNode();
2313 func_node_offset = kernel_loader.helper_.ReaderOffset();
2314
2315 {
2316 SafepointReadRwLocker ml(thread, thread->isolate_group()->program_lock());
2318 member_function, func_node_offset);
2319 if (!function.IsNull()) {
2320 return function.ptr();
2321 }
2322 }
2323 }
2324
2325 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
2327 member_function, func_node_offset);
2328 if (function.IsNull()) {
2329 ActiveClassScope active_class_scope(
2330 &kernel_loader.active_class_,
2331 &Class::Handle(zone, member_function.Owner()));
2332 ActiveMemberScope active_member(&kernel_loader.active_class_,
2333 &member_function);
2334 ActiveTypeParametersScope active_type_params(
2335 &kernel_loader.active_class_, member_function,
2336 &FunctionType::Handle(zone, parent_function.signature()), zone);
2337 kernel_loader.helper_.SetOffset(func_decl_offset);
2338 function =
2339 kernel_loader.LoadClosureFunction(parent_function, closure_owner);
2340 }
2341 return function.ptr();
2342}
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 336 of file kernel_loader.cc.

338 {
339 // Dill files can be concatenated (e.g. cat a.dill b.dill > c.dill), so we
340 // need to first index the (possibly combined) file.
341 // First entry becomes last entry.
342 // Last entry is for ease of calculating size of last subprogram.
343 subprogram_file_starts->Add(reader->size());
344 reader->set_offset(reader->size() - 4);
345 while (reader->offset() > 0) {
346 intptr_t size = reader->ReadUInt32();
347 intptr_t start = reader->offset() - size;
348 if (start < 0) {
349 FATAL("Invalid kernel binary: Indicated size is invalid.");
350 }
351 subprogram_file_starts->Add(start);
352 reader->set_offset(start - 4);
353 }
354 subprogram_file_starts->Reverse();
355}
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 236 of file kernel_loader.cc.

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

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

◆ LoadLibrary()

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

Definition at line 552 of file kernel_loader.cc.

552 {
553 // This will be invoked by VM bootstrapping code.
554 SafepointWriteRwLocker ml(thread_, thread_->isolate_group()->program_lock());
555
556 ASSERT(!library.Loaded());
557
558 const auto& uri = String::Handle(Z, library.url());
559 const intptr_t num_libraries = program_->library_count();
560 for (intptr_t i = 0; i < num_libraries; ++i) {
561 const String& library_uri = LibraryUri(i);
562 if (library_uri.Equals(uri)) {
563 LoadLibrary(i);
564 return;
565 }
566 }
567}
SafepointRwLock * program_lock()
Definition isolate.h:532
IsolateGroup * isolate_group() const
Definition thread.h:540
void LoadLibrary(const Library &library)

◆ LoadProgram()

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

Definition at line 499 of file kernel_loader.cc.

499 {
500 SafepointWriteRwLocker ml(thread_, thread_->isolate_group()->program_lock());
501 ASSERT(kernel_program_info_.constants() == Array::null());
502
503 if (!program_->is_single_program()) {
504 FATAL(
505 "Trying to load a concatenated dill file at a time where that is "
506 "not allowed");
507 }
508
509 LongJumpScope jump;
510 if (setjmp(*jump.Set()) == 0) {
511 // Note that `problemsAsJson` on Component is implicitly skipped.
512 const intptr_t length = program_->library_count();
513 for (intptr_t i = 0; i < length; i++) {
514 LoadLibrary(i);
515 }
516
517 // Finalize still pending classes if requested.
518 if (process_pending_classes) {
520 // Class finalization failed -> sticky error would be set.
521 return H.thread()->StealStickyError();
522 }
523 }
524
525 // Sets the constants array to an empty array with the length equal to
526 // the number of constants. The array gets filled lazily while reading
527 // constants.
528 ASSERT(kernel_program_info_.constants_table() != ExternalTypedData::null());
529 ConstantReader constant_reader(&helper_, &active_class_);
530 const intptr_t num_consts = constant_reader.NumConstants();
531 const Array& array = Array::Handle(Z, Array::New(num_consts, Heap::kOld));
532 for (intptr_t i = 0; i < num_consts; i++) {
533 array.SetAt(i, Object::sentinel());
534 }
535 kernel_program_info_.set_constants(array);
536 H.SetConstants(array); // for caching
537
538 NameIndex main = program_->main_method();
539 if (main != -1) {
540 NameIndex main_library = H.EnclosingName(main);
541 return LookupLibrary(main_library);
542 }
543
544 return Library::null();
545 }
546
547 // Either class finalization failed or we caught a compile error.
548 // In both cases sticky error would be set.
550}
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition object.h:10933
@ kOld
Definition heap.h:39
void set_constants(const Array &constants) const
Definition object.cc:15136
ArrayPtr constants() const
Definition object.h:5492
TypedDataViewPtr constants_table() const
Definition object.h:5483
DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError()
Definition thread.cc:243
size_t length
Definition main.py:1

◆ ReadLoadingUnits()

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

Definition at line 231 of file kernel_loader.cc.

231 {
232 LoadingUnitsMetadataHelper helper(&helper_);
233 helper.ReadLoadingUnits();
234}

◆ ReadObfuscationProhibitions()

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

Definition at line 226 of file kernel_loader.cc.

226 {
227 ObfuscationProhibitionsMetadataHelper helper(&helper_);
228 helper.ReadProhibitions();
229}

Friends And Related Symbol Documentation

◆ BuildingTranslationHelper

friend class BuildingTranslationHelper
friend

Definition at line 413 of file kernel_loader.h.


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