Flutter Engine
The Flutter Engine
kernel_loader.h
Go to the documentation of this file.
1// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_KERNEL_LOADER_H_
6#define RUNTIME_VM_KERNEL_LOADER_H_
7
8#if !defined(DART_PRECOMPILED_RUNTIME)
9
10#include "vm/bit_vector.h"
13#include "vm/hash_map.h"
14#include "vm/kernel.h"
15#include "vm/object.h"
16#include "vm/symbols.h"
17
18namespace dart {
19namespace kernel {
20
21class KernelLoader;
22
24 public:
27 Heap::Space space)
28 : TranslationHelper(thread, space),
29 loader_(loader),
30 library_lookup_handle_(Library::Handle(thread->zone())) {}
32
33 virtual LibraryPtr LookupLibraryByKernelLibrary(NameIndex library,
34 bool required = true);
35 virtual ClassPtr LookupClassByKernelClass(NameIndex klass,
36 bool required = true);
37
38 private:
39 KernelLoader* loader_;
40
41#if defined(DEBUG)
42 class LibraryLookupHandleScope {
43 public:
44 explicit LibraryLookupHandleScope(Library& lib) : lib_(lib) {
45 ASSERT(lib_.IsNull());
46 }
47
48 ~LibraryLookupHandleScope() { lib_ = Library::null(); }
49
50 private:
51 Library& lib_;
52
53 DISALLOW_COPY_AND_ASSIGN(LibraryLookupHandleScope);
54 };
55#endif // defined(DEBUG)
56
57 // Preallocated handle for use in LookupClassByKernelClass().
58 Library& library_lookup_handle_;
59
60 DISALLOW_COPY_AND_ASSIGN(BuildingTranslationHelper);
61};
62
63template <typename VmType>
64class Mapping {
65 public:
66 bool Lookup(intptr_t canonical_name, VmType** handle) {
67 typename MapType::Pair* pair = map_.LookupPair(canonical_name);
68 if (pair != nullptr) {
69 *handle = pair->value;
70 return true;
71 }
72 return false;
73 }
74
75 void Insert(intptr_t canonical_name, VmType* object) {
76 map_.Insert(canonical_name, object);
77 }
78
79 private:
80 typedef IntMap<VmType*> MapType;
81 MapType map_;
82};
83
85 public:
86 explicit LibraryIndex(const TypedDataView& kernel_data);
87
88 intptr_t class_count() const { return class_count_; }
89 intptr_t procedure_count() const { return procedure_count_; }
90
91 intptr_t ClassOffset(intptr_t index) const {
92 return reader_.ReadUInt32At(class_index_offset_ + index * 4);
93 }
94
95 intptr_t ProcedureOffset(intptr_t index) const {
96 return reader_.ReadUInt32At(procedure_index_offset_ + index * 4);
97 }
98
99 intptr_t SizeOfClassAtOffset(intptr_t class_offset) const {
100 for (intptr_t i = 0, offset = class_index_offset_; i < class_count_;
101 ++i, offset += 4) {
102 if (static_cast<intptr_t>(reader_.ReadUInt32At(offset)) == class_offset) {
103 return reader_.ReadUInt32At(offset + 4) - class_offset;
104 }
105 }
106 UNREACHABLE();
107 return -1;
108 }
109
110 intptr_t SourceReferencesOffset() { return source_references_offset_; }
111
112 private:
113 Reader reader_;
114 intptr_t source_references_offset_;
115 intptr_t class_index_offset_;
116 intptr_t class_count_;
117 intptr_t procedure_index_offset_;
118 intptr_t procedure_count_;
119
120 DISALLOW_COPY_AND_ASSIGN(LibraryIndex);
121};
122
124 public:
125 // |class_offset| is the offset of class' kernel data in |kernel_data|.
126 // The size of the class' kernel data is |class_size|.
127 ClassIndex(const TypedDataBase& kernel_data,
128 intptr_t class_offset,
129 intptr_t class_size);
130
131 intptr_t procedure_count() const { return procedure_count_; }
132
133 intptr_t ProcedureOffset(intptr_t index) const {
134 return reader_.ReadUInt32At(procedure_index_offset_ + index * 4);
135 }
136
137 private:
138 void Init(intptr_t class_offset, intptr_t class_size);
139
140 Reader reader_;
141 intptr_t procedure_count_;
142 intptr_t procedure_index_offset_;
143
144 DISALLOW_COPY_AND_ASSIGN(ClassIndex);
145};
146
149
150 const String* uri = nullptr;
151 const String* sources = nullptr;
152 const TypedData* line_starts = nullptr;
153};
154
159
160 static Key KeyOf(Pair kv) { return kv; }
161
162 static Value ValueOf(Pair kv) { return kv; }
163
164 static inline uword Hash(Key key) { return key->uri->Hash(); }
165
166 static inline bool IsKeyEqual(Pair kv, Key key) {
167 // Only compare uri.
168 return kv->uri->CompareTo(*key->uri) == 0;
169 }
170};
171
172class KernelLoader : public ValueObject {
173 public:
174 explicit KernelLoader(
175 Program* program,
177 static Object& LoadEntireProgram(Program* program,
178 bool process_pending_classes = true);
179
180 // Returns the library containing the main procedure, null if there
181 // was no main procedure, or a failure object if there was an error.
182 ObjectPtr LoadProgram(bool process_pending_classes = true);
183
184 // Load given library.
185 void LoadLibrary(const Library& library);
186
187 // Returns the function which will evaluate the expression, or a failure
188 // object if there was an error.
190 const String& klass);
191
192 // Finds all libraries that have been modified in this incremental
193 // version of the kernel program file.
194 //
195 // When [force_reload] is false and if [p_num_classes], [p_num_procedures] are
196 // not nullptr, then they are populated with number of classes and top-level
197 // procedures in [program].
198 static void FindModifiedLibraries(Program* program,
199 IsolateGroup* isolate_group,
200 BitVector* modified_libs,
201 bool force_reload,
202 bool* is_empty_program,
203 intptr_t* p_num_classes,
204 intptr_t* p_num_procedures);
205
206 static StringPtr FindSourceForScript(const uint8_t* kernel_buffer,
207 intptr_t kernel_buffer_length,
208 const String& url);
209
210 static void FinishLoading(const Class& klass);
211
213 void ReadLoadingUnits();
214
215 // Get closure Function from cache or create it if it is not created yet.
216 // [func_decl_offset] is an offset FunctionExpression or FunctionDeclaration.
217 static FunctionPtr GetClosureFunction(Thread* thread,
218 intptr_t func_decl_offset,
219 const Function& member_function,
220 const Function& parent_function,
221 const Object& closure_owner);
222
223 static void index_programs(kernel::Reader* reader,
224 GrowableArray<intptr_t>* subprogram_file_starts);
225
226 private:
227 // Pragma bits
236 using FfiNativePragma =
243
244 void FinishTopLevelClassLoading(const Class& toplevel_class,
245 const Library& library,
246 const LibraryIndex& library_index);
247
248 bool IsClassName(NameIndex name, const String& library, const String& klass);
249
250 void ReadVMAnnotations(intptr_t annotation_count,
251 uint32_t* pragma_bits,
252 String* native_name = nullptr);
253
254 KernelLoader(const KernelProgramInfo& kernel_program_info,
255 const TypedDataBase& kernel_data,
256 intptr_t data_program_offset);
257
258 void InitializeFields(
260
261 LibraryPtr LoadLibrary(intptr_t index);
262
263 const String& LibraryUri(intptr_t library_index) {
264 return translation_helper_.DartSymbolPlain(
265 translation_helper_.CanonicalNameString(
266 library_canonical_name(library_index)));
267 }
268
269 intptr_t library_offset(intptr_t index) {
270 kernel::Reader reader(program_->binary());
271 return reader.ReadFromIndexNoReset(reader.size(),
273 program_->library_count() + 1, index);
274 }
275
276 NameIndex library_canonical_name(intptr_t index) {
277 kernel::Reader reader(program_->binary());
278 reader.set_offset(library_offset(index));
279
280 // Start reading library.
281 // Note that this needs to be keep in sync with LibraryHelper.
282 reader.ReadFlags();
283 reader.ReadUInt(); // Read major language version.
284 reader.ReadUInt(); // Read minor language version.
285 return reader.ReadCanonicalNameReference();
286 }
287
288 uint8_t CharacterAt(StringIndex string_index, intptr_t index);
289
290 void walk_incremental_kernel(BitVector* modified_libs,
291 bool* is_empty_program,
292 intptr_t* p_num_classes,
293 intptr_t* p_num_procedures);
294
295 void LoadPreliminaryClass(ClassHelper* class_helper,
296 intptr_t type_parameter_count);
297
298 void ReadInferredType(const Field& field, intptr_t kernel_offset);
299 void CheckForInitializer(const Field& field);
300
301 void LoadClass(const Library& library,
302 const Class& toplevel_class,
303 intptr_t class_end,
304 Class* out_class);
305
306 void FinishClassLoading(const Class& klass,
307 const Library& library,
308 const Class& toplevel_class,
309 intptr_t class_offset,
310 const ClassIndex& class_index,
311 ClassHelper* class_helper);
312
313 void LoadProcedure(const Library& library,
314 const Class& owner,
315 bool in_class,
316 intptr_t procedure_end);
317
318 ArrayPtr MakeFieldsArray();
319 ArrayPtr MakeFunctionsArray();
320
321 ScriptPtr LoadScriptAt(
322 intptr_t index,
323 DirectChainedHashMap<UriToSourceTableTrait>* uri_to_source_table);
324
325 // If klass's script is not the script at the uri index, return a PatchClass
326 // for klass whose script corresponds to the uri index.
327 // Otherwise return klass.
328 const Object& ClassForScriptAt(const Class& klass, intptr_t source_uri_index);
329 ScriptPtr ScriptAt(intptr_t source_uri_index) {
330 return kernel_program_info_.ScriptAt(source_uri_index);
331 }
332
333 // Reads field initializer and returns the initial field value.
334 ObjectPtr ReadInitialFieldValue(const Field& field,
335 FieldHelper* field_helper);
336
337 // Generates field getter and setter functions.
338 void GenerateFieldAccessors(const Class& klass,
339 const Field& field,
340 FieldHelper* field_helper);
341
342 void LoadLibraryImportsAndExports(Library* library,
343 const Class& toplevel_class);
344
345 LibraryPtr LookupLibraryOrNull(NameIndex library);
346 LibraryPtr LookupLibrary(NameIndex library);
347 LibraryPtr LookupLibraryFromClass(NameIndex klass);
348 ClassPtr LookupClass(const Library& library, NameIndex klass);
349
350 UntaggedFunction::Kind GetFunctionType(ProcedureHelper::Kind procedure_kind);
351
352 // Read local function (either FunctionExpression or FunctionDeclaration)
353 // and create corresponding Function object.
354 // If [closure_owner] is not null, it overrides closure function owner.
355 FunctionPtr LoadClosureFunction(const Function& parent_function,
356 const Object& closure_owner);
357
358 Program* program_;
359
360 Thread* thread_;
361 Zone* zone_;
362 NoActiveIsolateScope no_active_isolate_scope_;
363 Array& patch_classes_;
364 ActiveClass active_class_;
365 // This is the offset of the current library within
366 // the whole kernel program.
367 intptr_t library_kernel_offset_;
368 // This is the offset by which offsets, which are set relative
369 // to their library's kernel data, have to be corrected.
370 intptr_t correction_offset_;
371 bool loading_native_wrappers_library_;
372
373 NameIndex skip_vmservice_library_;
374
375 TypedDataView& library_kernel_data_;
376 KernelProgramInfo& kernel_program_info_;
377 BuildingTranslationHelper translation_helper_;
378 KernelReaderHelper helper_;
379 ConstantReader constant_reader_;
380 TypeTranslator type_translator_;
381 InferredTypeMetadataHelper inferred_type_metadata_helper_;
382
383 Object& static_field_value_;
384
385 Smi& name_index_handle_;
386
387 // We "re-use" the normal .dill file format for encoding compiled evaluation
388 // expressions from the debugger. This allows us to also reuse the normal
389 // a) kernel loader b) flow graph building code. The encoding is either one
390 // of the following two options:
391 //
392 // * Option a) The expression is evaluated inside an instance method call
393 // context:
394 //
395 // Program:
396 // |> library "evaluate:source"
397 // |> class "#DebugClass"
398 // |> procedure ":Eval"
399 //
400 // * Option b) The expression is evaluated outside an instance method call
401 // context:
402 //
403 // Program:
404 // |> library "evaluate:source"
405 // |> procedure ":Eval"
406 //
407 // See
408 // * pkg/front_end/lib/src/fasta/incremental_compiler.dart,
409 // compileExpression
410 // * pkg/front_end/lib/src/fasta/kernel/utils.dart,
411 // createExpressionEvaluationComponent
412 //
413 Library& expression_evaluation_library_;
414
415 GrowableArray<const Function*> functions_;
416 GrowableArray<const Field*> fields_;
417
419
421};
422
423FunctionPtr CreateFieldInitializerFunction(Thread* thread,
424 Zone* zone,
425 const Field& field);
426
427} // namespace kernel
428} // namespace dart
429
430#endif // !defined(DART_PRECOMPILED_RUNTIME)
431#endif // RUNTIME_VM_KERNEL_LOADER_H_
#define UNREACHABLE()
Definition: assert.h:248
Pair * LookupPair(const Key &key) const
Definition: hash_map.h:558
void Insert(const Key &key, const Value &value)
Definition: hash_map.h:543
ScriptPtr ScriptAt(intptr_t index) const
Definition: object.cc:15079
static ObjectPtr null()
Definition: object.h:433
intptr_t CompareTo(const String &other) const
Definition: object.cc:23638
virtual ClassPtr LookupClassByKernelClass(NameIndex klass, bool required=true)
BuildingTranslationHelper(KernelLoader *loader, Thread *thread, Heap::Space space)
Definition: kernel_loader.h:25
virtual LibraryPtr LookupLibraryByKernelLibrary(NameIndex library, bool required=true)
intptr_t procedure_count() const
ClassIndex(const TypedDataBase &kernel_data, intptr_t class_offset, intptr_t class_size)
intptr_t ProcedureOffset(intptr_t index) const
static Object & LoadEntireProgram(Program *program, bool process_pending_classes=true)
static void index_programs(kernel::Reader *reader, GrowableArray< intptr_t > *subprogram_file_starts)
ObjectPtr LoadExpressionEvaluationFunction(const String &library_url, const String &klass)
void LoadLibrary(const Library &library)
friend class BuildingTranslationHelper
KernelLoader(Program *program, DirectChainedHashMap< UriToSourceTableTrait > *uri_to_source_table)
static StringPtr FindSourceForScript(const uint8_t *kernel_buffer, intptr_t kernel_buffer_length, const String &url)
static void FinishLoading(const Class &klass)
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)
ObjectPtr LoadProgram(bool process_pending_classes=true)
static FunctionPtr GetClosureFunction(Thread *thread, intptr_t func_decl_offset, const Function &member_function, const Function &parent_function, const Object &closure_owner)
intptr_t SizeOfClassAtOffset(intptr_t class_offset) const
Definition: kernel_loader.h:99
intptr_t class_count() const
Definition: kernel_loader.h:88
intptr_t procedure_count() const
Definition: kernel_loader.h:89
intptr_t ProcedureOffset(intptr_t index) const
Definition: kernel_loader.h:95
LibraryIndex(const TypedDataView &kernel_data)
intptr_t ClassOffset(intptr_t index) const
Definition: kernel_loader.h:91
bool Lookup(intptr_t canonical_name, VmType **handle)
Definition: kernel_loader.h:66
void Insert(intptr_t canonical_name, VmType *object)
Definition: kernel_loader.h:75
intptr_t library_count()
Definition: kernel.h:92
const TypedDataBase & binary()
Definition: kernel.h:95
uint32_t ReadUInt32At(intptr_t offset) const
const String & DartSymbolPlain(const char *content) const
StringIndex CanonicalNameString(NameIndex name)
#define ASSERT(E)
FunctionPtr CreateFieldInitializerFunction(Thread *thread, Zone *zone, const Field &field)
static constexpr int LibraryCountFieldCountFromEnd
Definition: dart_vm.cc:33
const char *const name
uintptr_t uword
Definition: globals.h:501
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:581
SeparatedVector2 offset
UriToSourceTableEntry * Pair
static bool IsKeyEqual(Pair kv, Key key)
const UriToSourceTableEntry * Key
UriToSourceTableEntry * Value