2 * Copyright (C) 2011 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #ifndef ART_COMPILER_OAT_WRITER_H_
18 #define ART_COMPILER_OAT_WRITER_H_
24 #include "base/array_ref.h"
25 #include "base/dchecked_vector.h"
26 #include "linker/relative_patcher.h" // For linker::RelativePatcherTargetProvider.
28 #include "method_reference.h"
29 #include "mirror/class.h"
33 #include "string_reference.h"
34 #include "utils/type_reference.h"
42 class ProfileCompilationInfo;
45 class TypeLookupTable;
50 struct MethodDebugInfo;
54 class MultiOatRelativePatcher;
59 } // namespace verifier
61 // OatHeader variable length with count of D OatDexFiles
63 // OatDexFile[0] one variable sized OatDexFile with offsets to Dex and OatClasses
68 // TypeLookupTable[0] one descriptor to class def index hash table for each OatDexFile.
73 // ClassOffsets[0] one table of OatClass offsets for each class def for each OatDexFile.
78 // OatClass[0] one variable sized OatClass for each of C DexFile::ClassDefs
79 // OatClass[1] contains OatClass entries with class status, offsets to code, etc.
83 // GcMap one variable sized blob with GC map.
84 // GcMap GC maps are deduplicated.
88 // VmapTable one variable sized VmapTable blob (quick compiler only).
89 // VmapTable VmapTables are deduplicated.
93 // MappingTable one variable sized blob with MappingTable (quick compiler only).
94 // MappingTable MappingTables are deduplicated.
98 // padding if necessary so that the following code will be page aligned
100 // OatMethodHeader fixed size header for a CompiledMethod including the size of the MethodCode.
101 // MethodCode one variable sized blob with the code of a CompiledMethod.
102 // OatMethodHeader (OatMethodHeader, MethodCode) pairs are deduplicated.
110 enum class CreateTypeLookupTable {
116 OatWriter(bool compiling_boot_image, TimingLogger* timings, ProfileCompilationInfo* info);
118 // To produce a valid oat file, the user must first add sources with any combination of
119 // - AddDexFileSource(),
120 // - AddZippedDexFilesSource(),
121 // - AddRawDexFileSource(),
122 // - AddVdexDexFilesSource().
123 // Then the user must call in order
124 // - WriteAndOpenDexFiles()
126 // - WriteVerifierDeps()
127 // - WriteQuickeningInfo()
128 // - WriteChecksumsAndVdexHeader()
129 // - PrepareLayout(),
134 // Add dex file source(s) from a file, either a plain dex file or
135 // a zip file with one or more dex files.
136 bool AddDexFileSource(
137 const char* filename,
138 const char* location,
139 CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault);
140 // Add dex file source(s) from a zip file specified by a file handle.
141 bool AddZippedDexFilesSource(
143 const char* location,
144 CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault);
145 // Add dex file source from raw memory.
146 bool AddRawDexFileSource(
147 const ArrayRef<const uint8_t>& data,
148 const char* location,
149 uint32_t location_checksum,
150 CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault);
151 // Add dex file source(s) from a vdex file.
152 bool AddVdexDexFilesSource(
153 const VdexFile& vdex_file,
154 const char* location,
155 CreateTypeLookupTable create_type_lookup_table = CreateTypeLookupTable::kDefault);
156 dchecked_vector<const char*> GetSourceLocations() const;
158 // Write raw dex files to the vdex file, mmap the file and open the dex files from it.
159 // Supporting data structures are written into the .rodata section of the oat file.
160 // The `verify` setting dictates whether the dex file verifier should check the dex files.
161 // This is generally the case, and should only be false for tests.
162 // If `update_input_vdex` is true, then this method won't actually write the dex files,
163 // and the compiler will just re-use the existing vdex file.
164 bool WriteAndOpenDexFiles(File* vdex_file,
165 OutputStream* oat_rodata,
166 InstructionSet instruction_set,
167 const InstructionSetFeatures* instruction_set_features,
168 SafeMap<std::string, std::string>* key_value_store,
170 bool update_input_vdex,
171 /*out*/ std::unique_ptr<MemMap>* opened_dex_files_map,
172 /*out*/ std::vector<std::unique_ptr<const DexFile>>* opened_dex_files);
173 bool WriteQuickeningInfo(OutputStream* vdex_out);
174 bool WriteVerifierDeps(OutputStream* vdex_out, verifier::VerifierDeps* verifier_deps);
175 bool WriteChecksumsAndVdexHeader(OutputStream* vdex_out);
176 // Initialize the writer with the given parameters.
177 void Initialize(const CompilerDriver* compiler,
178 ImageWriter* image_writer,
179 const std::vector<const DexFile*>& dex_files) {
180 compiler_driver_ = compiler;
181 image_writer_ = image_writer;
182 dex_files_ = &dex_files;
185 // Prepare layout of remaining data.
186 void PrepareLayout(linker::MultiOatRelativePatcher* relative_patcher);
187 // Write the rest of .rodata section (ClassOffsets[], OatClass[], maps).
188 bool WriteRodata(OutputStream* out);
189 // Write the code to the .text section.
190 bool WriteCode(OutputStream* out);
191 // Write the oat header. This finalizes the oat file.
192 bool WriteHeader(OutputStream* out,
193 uint32_t image_file_location_oat_checksum,
194 uintptr_t image_file_location_oat_begin,
195 int32_t image_patch_delta);
197 // Returns whether the oat file has an associated image.
198 bool HasImage() const {
199 // Since the image is being created at the same time as the oat file,
200 // check if there's an image writer.
201 return image_writer_ != nullptr;
204 bool HasBootImage() const {
205 return compiling_boot_image_;
208 const OatHeader& GetOatHeader() const {
212 size_t GetOatSize() const {
216 size_t GetBssSize() const {
220 size_t GetBssRootsOffset() const {
221 return bss_roots_offset_;
224 size_t GetOatDataOffset() const {
225 return oat_data_offset_;
230 void AddMethodDebugInfos(const std::vector<debug::MethodDebugInfo>& infos) {
231 method_info_.insert(method_info_.end(), infos.begin(), infos.end());
234 ArrayRef<const debug::MethodDebugInfo> GetMethodDebugInfo() const {
235 return ArrayRef<const debug::MethodDebugInfo>(method_info_);
238 const CompilerDriver* GetCompilerDriver() {
239 return compiler_driver_;
247 // The function VisitDexMethods() below iterates through all the methods in all
248 // the compiled dex files in order of their definitions. The method visitor
249 // classes provide individual bits of processing for each of the passes we need to
250 // first collect the data we want to write to the oat file and then, in later passes,
251 // to actually write it.
252 class DexMethodVisitor;
253 class OatDexMethodVisitor;
254 class InitOatClassesMethodVisitor;
255 class InitCodeMethodVisitor;
256 class InitMapMethodVisitor;
257 class InitMethodInfoVisitor;
258 class InitImageMethodVisitor;
259 class WriteCodeMethodVisitor;
260 class WriteMapMethodVisitor;
261 class WriteMethodInfoVisitor;
262 class WriteQuickeningInfoMethodVisitor;
264 // Visit all the methods in all the compiled dex files in their definition order
265 // with a given DexMethodVisitor.
266 bool VisitDexMethods(DexMethodVisitor* visitor);
268 // If `update_input_vdex` is true, then this method won't actually write the dex files,
269 // and the compiler will just re-use the existing vdex file.
270 bool WriteDexFiles(OutputStream* out, File* file, bool update_input_vdex);
271 bool WriteDexFile(OutputStream* out,
273 OatDexFile* oat_dex_file,
274 bool update_input_vdex);
275 bool SeekToDexFile(OutputStream* out, File* file, OatDexFile* oat_dex_file);
276 bool LayoutAndWriteDexFile(OutputStream* out, OatDexFile* oat_dex_file);
277 bool WriteDexFile(OutputStream* out,
279 OatDexFile* oat_dex_file,
281 bool WriteDexFile(OutputStream* out,
283 OatDexFile* oat_dex_file,
285 bool WriteDexFile(OutputStream* out,
286 OatDexFile* oat_dex_file,
287 const uint8_t* dex_file,
288 bool update_input_vdex);
289 bool OpenDexFiles(File* file,
291 /*out*/ std::unique_ptr<MemMap>* opened_dex_files_map,
292 /*out*/ std::vector<std::unique_ptr<const DexFile>>* opened_dex_files);
294 size_t InitOatHeader(InstructionSet instruction_set,
295 const InstructionSetFeatures* instruction_set_features,
296 uint32_t num_dex_files,
297 SafeMap<std::string, std::string>* key_value_store);
298 size_t InitOatDexFiles(size_t offset);
299 size_t InitOatClasses(size_t offset);
300 size_t InitOatMaps(size_t offset);
301 size_t InitOatCode(size_t offset);
302 size_t InitOatCodeDexFiles(size_t offset);
303 void InitBssLayout(InstructionSet instruction_set);
305 bool WriteClassOffsets(OutputStream* out);
306 bool WriteClasses(OutputStream* out);
307 size_t WriteMaps(OutputStream* out, const size_t file_offset, size_t relative_offset);
308 size_t WriteCode(OutputStream* out, const size_t file_offset, size_t relative_offset);
309 size_t WriteCodeDexFiles(OutputStream* out, const size_t file_offset, size_t relative_offset);
311 bool RecordOatDataOffset(OutputStream* out);
312 bool ReadDexFileHeader(File* oat_file, OatDexFile* oat_dex_file);
313 bool ValidateDexFileHeader(const uint8_t* raw_header, const char* location);
314 bool WriteOatDexFiles(OutputStream* oat_rodata);
315 bool WriteTypeLookupTables(OutputStream* oat_rodata,
316 const std::vector<std::unique_ptr<const DexFile>>& opened_dex_files);
317 bool WriteCodeAlignment(OutputStream* out, uint32_t aligned_code_delta);
318 void SetMultiOatRelativePatcherAdjustment();
321 enum class WriteState {
322 kAddingDexFileSources,
330 WriteState write_state_;
331 TimingLogger* timings_;
333 std::vector<std::unique_ptr<File>> raw_dex_files_;
334 std::vector<std::unique_ptr<ZipArchive>> zip_archives_;
335 std::vector<std::unique_ptr<ZipEntry>> zipped_dex_files_;
337 // Using std::list<> which doesn't move elements around on push/emplace_back().
338 // We need this because we keep plain pointers to the strings' c_str().
339 std::list<std::string> zipped_dex_file_locations_;
341 dchecked_vector<debug::MethodDebugInfo> method_info_;
343 const CompilerDriver* compiler_driver_;
344 ImageWriter* image_writer_;
345 const bool compiling_boot_image_;
347 // note OatFile does not take ownership of the DexFiles
348 const std::vector<const DexFile*>* dex_files_;
350 // Size required for Vdex data structures.
353 // Offset of section holding Dex files inside Vdex.
354 size_t vdex_dex_files_offset_;
356 // Offset of section holding VerifierDeps inside Vdex.
357 size_t vdex_verifier_deps_offset_;
359 // Offset of section holding quickening info inside Vdex.
360 size_t vdex_quickening_info_offset_;
362 // Size required for Oat data structures.
365 // The start of the required .bss section.
368 // The size of the required .bss section holding the DexCache data and GC roots.
371 // The offset of the GC roots in .bss section.
372 size_t bss_roots_offset_;
374 // Map for allocating Class entries in .bss. Indexed by TypeReference for the source
375 // type in the dex file with the "type value comparator" for deduplication. The value
376 // is the target offset for patching, starting at `bss_start_ + bss_roots_offset_`.
377 SafeMap<TypeReference, size_t, TypeReferenceValueComparator> bss_type_entries_;
379 // Map for allocating String entries in .bss. Indexed by StringReference for the source
380 // string in the dex file with the "string value comparator" for deduplication. The value
381 // is the target offset for patching, starting at `bss_start_ + bss_roots_offset_`.
382 SafeMap<StringReference, size_t, StringReferenceValueComparator> bss_string_entries_;
384 // Offsets of the dex cache arrays for each app dex file. For the
385 // boot image, this information is provided by the ImageWriter.
386 SafeMap<const DexFile*, size_t> dex_cache_arrays_offsets_; // DexFiles not owned.
388 // Offset of the oat data from the start of the mmapped region of the elf file.
389 size_t oat_data_offset_;
391 // Fake OatDexFiles to hold type lookup tables for the compiler.
392 std::vector<std::unique_ptr<art::OatDexFile>> type_lookup_table_oat_dex_files_;
395 std::unique_ptr<OatHeader> oat_header_;
396 dchecked_vector<OatDexFile> oat_dex_files_;
397 dchecked_vector<OatClass> oat_classes_;
398 std::unique_ptr<const std::vector<uint8_t>> jni_dlsym_lookup_;
399 std::unique_ptr<const std::vector<uint8_t>> quick_generic_jni_trampoline_;
400 std::unique_ptr<const std::vector<uint8_t>> quick_imt_conflict_trampoline_;
401 std::unique_ptr<const std::vector<uint8_t>> quick_resolution_trampoline_;
402 std::unique_ptr<const std::vector<uint8_t>> quick_to_interpreter_bridge_;
405 uint32_t size_vdex_header_;
406 uint32_t size_vdex_checksums_;
407 uint32_t size_dex_file_alignment_;
408 uint32_t size_executable_offset_alignment_;
409 uint32_t size_oat_header_;
410 uint32_t size_oat_header_key_value_store_;
411 uint32_t size_dex_file_;
412 uint32_t size_verifier_deps_;
413 uint32_t size_verifier_deps_alignment_;
414 uint32_t size_quickening_info_;
415 uint32_t size_quickening_info_alignment_;
416 uint32_t size_interpreter_to_interpreter_bridge_;
417 uint32_t size_interpreter_to_compiled_code_bridge_;
418 uint32_t size_jni_dlsym_lookup_;
419 uint32_t size_quick_generic_jni_trampoline_;
420 uint32_t size_quick_imt_conflict_trampoline_;
421 uint32_t size_quick_resolution_trampoline_;
422 uint32_t size_quick_to_interpreter_bridge_;
423 uint32_t size_trampoline_alignment_;
424 uint32_t size_method_header_;
426 uint32_t size_code_alignment_;
427 uint32_t size_relative_call_thunks_;
428 uint32_t size_misc_thunks_;
429 uint32_t size_vmap_table_;
430 uint32_t size_method_info_;
431 uint32_t size_oat_dex_file_location_size_;
432 uint32_t size_oat_dex_file_location_data_;
433 uint32_t size_oat_dex_file_location_checksum_;
434 uint32_t size_oat_dex_file_offset_;
435 uint32_t size_oat_dex_file_class_offsets_offset_;
436 uint32_t size_oat_dex_file_lookup_table_offset_;
437 uint32_t size_oat_lookup_table_alignment_;
438 uint32_t size_oat_lookup_table_;
439 uint32_t size_oat_class_offsets_alignment_;
440 uint32_t size_oat_class_offsets_;
441 uint32_t size_oat_class_type_;
442 uint32_t size_oat_class_status_;
443 uint32_t size_oat_class_method_bitmaps_;
444 uint32_t size_oat_class_method_offsets_;
446 // The helper for processing relative patches is external so that we can patch across oat files.
447 linker::MultiOatRelativePatcher* relative_patcher_;
449 // The locations of absolute patches relative to the start of the executable section.
450 dchecked_vector<uintptr_t> absolute_patch_locations_;
452 // Profile info used to generate new layout of files.
453 ProfileCompilationInfo* profile_compilation_info_;
455 DISALLOW_COPY_AND_ASSIGN(OatWriter);
460 #endif // ART_COMPILER_OAT_WRITER_H_