image_writer.h revision a59dd80f9f48cb750d329d4d4af2d99d72b484d1
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17#ifndef ART_COMPILER_IMAGE_WRITER_H_ 18#define ART_COMPILER_IMAGE_WRITER_H_ 19 20#include <stdint.h> 21 22#include <cstddef> 23#include <memory> 24#include <set> 25#include <string> 26 27#include "driver/compiler_driver.h" 28#include "mem_map.h" 29#include "oat_file.h" 30#include "mirror/dex_cache.h" 31#include "os.h" 32#include "safe_map.h" 33#include "gc/space/space.h" 34 35namespace art { 36 37// Write a Space built during compilation for use during execution. 38class ImageWriter { 39 public: 40 explicit ImageWriter(const CompilerDriver& compiler_driver) 41 : compiler_driver_(compiler_driver), oat_file_(NULL), image_end_(0), image_begin_(NULL), 42 oat_data_begin_(NULL), interpreter_to_interpreter_bridge_offset_(0), 43 interpreter_to_compiled_code_bridge_offset_(0), portable_imt_conflict_trampoline_offset_(0), 44 portable_resolution_trampoline_offset_(0), quick_generic_jni_trampoline_offset_(0), 45 quick_imt_conflict_trampoline_offset_(0), quick_resolution_trampoline_offset_(0) {} 46 47 ~ImageWriter() {} 48 49 bool Write(const std::string& image_filename, 50 uintptr_t image_begin, 51 const std::string& oat_filename, 52 const std::string& oat_location) 53 LOCKS_EXCLUDED(Locks::mutator_lock_); 54 55 uintptr_t GetOatDataBegin() { 56 return reinterpret_cast<uintptr_t>(oat_data_begin_); 57 } 58 59 private: 60 bool AllocMemory(); 61 62 // Mark the objects defined in this space in the given live bitmap. 63 void RecordImageAllocations() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 64 65 // We use the lock word to store the offset of the object in the image. 66 void AssignImageOffset(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 67 void SetImageOffset(mirror::Object* object, size_t offset) 68 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 69 bool IsImageOffsetAssigned(mirror::Object* object) const 70 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 71 size_t GetImageOffset(mirror::Object* object) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 72 73 static void* GetImageAddressCallback(void* writer, mirror::Object* obj) 74 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 75 return reinterpret_cast<ImageWriter*>(writer)->GetImageAddress(obj); 76 } 77 78 mirror::Object* GetImageAddress(mirror::Object* object) const 79 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 80 if (object == NULL) { 81 return NULL; 82 } 83 return reinterpret_cast<mirror::Object*>(image_begin_ + GetImageOffset(object)); 84 } 85 86 mirror::Object* GetLocalAddress(mirror::Object* object) const 87 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 88 size_t offset = GetImageOffset(object); 89 byte* dst = image_->Begin() + offset; 90 return reinterpret_cast<mirror::Object*>(dst); 91 } 92 93 const byte* GetOatAddress(uint32_t offset) const { 94#if !defined(ART_USE_PORTABLE_COMPILER) 95 // With Quick, code is within the OatFile, as there are all in one 96 // .o ELF object. However with Portable, the code is always in 97 // different .o ELF objects. 98 DCHECK_LT(offset, oat_file_->Size()); 99#endif 100 if (offset == 0) { 101 return NULL; 102 } 103 return oat_data_begin_ + offset; 104 } 105 106 // Returns true if the class was in the original requested image classes list. 107 bool IsImageClass(mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 108 109 // Debug aid that list of requested image classes. 110 void DumpImageClasses(); 111 112 // Preinitializes some otherwise lazy fields (such as Class name) to avoid runtime image dirtying. 113 void ComputeLazyFieldsForImageClasses() 114 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 115 static bool ComputeLazyFieldsForClassesVisitor(mirror::Class* klass, void* arg) 116 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 117 118 // Wire dex cache resolved strings to strings in the image to avoid runtime resolution. 119 void ComputeEagerResolvedStrings() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 120 static void ComputeEagerResolvedStringsCallback(mirror::Object* obj, void* arg) 121 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 122 123 // Remove unwanted classes from various roots. 124 void PruneNonImageClasses() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 125 static bool NonImageClassesVisitor(mirror::Class* c, void* arg) 126 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 127 128 // Verify unwanted classes removed. 129 void CheckNonImageClassesRemoved(); 130 static void CheckNonImageClassesRemovedCallback(mirror::Object* obj, void* arg) 131 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 132 133 // Lays out where the image objects will be at runtime. 134 void CalculateNewObjectOffsets(size_t oat_loaded_size, size_t oat_data_offset) 135 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 136 mirror::ObjectArray<mirror::Object>* CreateImageRoots() const 137 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 138 void CalculateObjectOffsets(mirror::Object* obj) 139 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 140 141 void WalkInstanceFields(mirror::Object* obj, mirror::Class* klass) 142 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 143 void WalkFieldsInOrder(mirror::Object* obj) 144 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 145 static void WalkFieldsCallback(mirror::Object* obj, void* arg) 146 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 147 148 // Creates the contiguous image in memory and adjusts pointers. 149 void CopyAndFixupObjects(); 150 static void CopyAndFixupObjectsCallback(mirror::Object* obj, void* arg) 151 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 152 void FixupMethod(mirror::ArtMethod* orig, mirror::ArtMethod* copy) 153 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 154 void FixupObject(mirror::Object* orig, mirror::Object* copy) 155 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 156 157 // Get quick code for non-resolution/imt_conflict/abstract method. 158 const byte* GetQuickCode(mirror::ArtMethod* method, bool* quick_is_interpreted) 159 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 160 161 const byte* GetQuickEntryPoint(mirror::ArtMethod* method) 162 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 163 164 // Patches references in OatFile to expect runtime addresses. 165 void PatchOatCodeAndMethods(File* elf_file) 166 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 167 168 const CompilerDriver& compiler_driver_; 169 170 // oat file with code for this image 171 OatFile* oat_file_; 172 173 // Memory mapped for generating the image. 174 std::unique_ptr<MemMap> image_; 175 176 // Offset to the free space in image_. 177 size_t image_end_; 178 179 // Beginning target image address for the output image. 180 byte* image_begin_; 181 182 // Saved hashes (objects are inside of the image so that they don't move). 183 std::vector<std::pair<mirror::Object*, uint32_t>> saved_hashes_; 184 185 // Beginning target oat address for the pointers from the output image to its oat file. 186 const byte* oat_data_begin_; 187 188 // Image bitmap which lets us know where the objects inside of the image reside. 189 std::unique_ptr<gc::accounting::ContinuousSpaceBitmap> image_bitmap_; 190 191 // Offset from oat_data_begin_ to the stubs. 192 uint32_t interpreter_to_interpreter_bridge_offset_; 193 uint32_t interpreter_to_compiled_code_bridge_offset_; 194 uint32_t jni_dlsym_lookup_offset_; 195 uint32_t portable_imt_conflict_trampoline_offset_; 196 uint32_t portable_resolution_trampoline_offset_; 197 uint32_t portable_to_interpreter_bridge_offset_; 198 uint32_t quick_generic_jni_trampoline_offset_; 199 uint32_t quick_imt_conflict_trampoline_offset_; 200 uint32_t quick_resolution_trampoline_offset_; 201 uint32_t quick_to_interpreter_bridge_offset_; 202 203 friend class FixupVisitor; 204 friend class FixupClassVisitor; 205 DISALLOW_COPY_AND_ASSIGN(ImageWriter); 206}; 207 208} // namespace art 209 210#endif // ART_COMPILER_IMAGE_WRITER_H_ 211