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 <set> 24 #include <string> 25 26 #include "driver/compiler_driver.h" 27 #include "mem_map.h" 28 #include "oat_file.h" 29 #include "mirror/dex_cache.h" 30 #include "os.h" 31 #include "safe_map.h" 32 #include "gc/space/space.h" 33 #include "UniquePtr.h" 34 35 namespace art { 36 37 // Write a Space built during compilation for use during execution. 38 class ImageWriter { 39 public: ImageWriter(const CompilerDriver & compiler_driver)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_resolution_trampoline_offset_(0), 44 quick_resolution_trampoline_offset_(0) {} 45 ~ImageWriter()46 ~ImageWriter() {} 47 48 bool Write(const std::string& image_filename, 49 uintptr_t image_begin, 50 const std::string& oat_filename, 51 const std::string& oat_location) 52 LOCKS_EXCLUDED(Locks::mutator_lock_); 53 GetOatDataBegin()54 uintptr_t GetOatDataBegin() { 55 return reinterpret_cast<uintptr_t>(oat_data_begin_); 56 } 57 58 private: 59 bool AllocMemory(); 60 61 // Mark the objects defined in this space in the given live bitmap. 62 void RecordImageAllocations() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 63 64 // We use the lock word to store the offset of the object in the image. AssignImageOffset(mirror::Object * object)65 void AssignImageOffset(mirror::Object* object) 66 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 67 DCHECK(object != NULL); 68 SetImageOffset(object, image_end_); 69 image_end_ += RoundUp(object->SizeOf(), 8); // 64-bit alignment 70 DCHECK_LT(image_end_, image_->Size()); 71 } 72 SetImageOffset(mirror::Object * object,size_t offset)73 void SetImageOffset(mirror::Object* object, size_t offset) { 74 DCHECK(object != NULL); 75 DCHECK_NE(offset, 0U); 76 DCHECK(!IsImageOffsetAssigned(object)); 77 offsets_.Put(object, offset); 78 } 79 IsImageOffsetAssigned(const mirror::Object * object)80 size_t IsImageOffsetAssigned(const mirror::Object* object) const { 81 DCHECK(object != NULL); 82 return offsets_.find(object) != offsets_.end(); 83 } 84 GetImageOffset(const mirror::Object * object)85 size_t GetImageOffset(const mirror::Object* object) const { 86 DCHECK(object != NULL); 87 DCHECK(IsImageOffsetAssigned(object)); 88 return offsets_.find(object)->second; 89 } 90 GetImageAddress(const mirror::Object * object)91 mirror::Object* GetImageAddress(const mirror::Object* object) const { 92 if (object == NULL) { 93 return NULL; 94 } 95 return reinterpret_cast<mirror::Object*>(image_begin_ + GetImageOffset(object)); 96 } 97 GetLocalAddress(const mirror::Object * object)98 mirror::Object* GetLocalAddress(const mirror::Object* object) const { 99 size_t offset = GetImageOffset(object); 100 byte* dst = image_->Begin() + offset; 101 return reinterpret_cast<mirror::Object*>(dst); 102 } 103 GetOatAddress(uint32_t offset)104 const byte* GetOatAddress(uint32_t offset) const { 105 #if !defined(ART_USE_PORTABLE_COMPILER) 106 // With Quick, code is within the OatFile, as there are all in one 107 // .o ELF object. However with Portable, the code is always in 108 // different .o ELF objects. 109 DCHECK_LT(offset, oat_file_->Size()); 110 #endif 111 if (offset == 0) { 112 return NULL; 113 } 114 return oat_data_begin_ + offset; 115 } 116 117 // Returns true if the class was in the original requested image classes list. 118 bool IsImageClass(const mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 119 120 // Debug aid that list of requested image classes. 121 void DumpImageClasses(); 122 123 // Preinitializes some otherwise lazy fields (such as Class name) to avoid runtime image dirtying. 124 void ComputeLazyFieldsForImageClasses() 125 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 126 static bool ComputeLazyFieldsForClassesVisitor(mirror::Class* klass, void* arg) 127 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 128 129 // Wire dex cache resolved strings to strings in the image to avoid runtime resolution. 130 void ComputeEagerResolvedStrings(); 131 static void ComputeEagerResolvedStringsCallback(mirror::Object* obj, void* arg) 132 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 133 134 // Remove unwanted classes from various roots. 135 void PruneNonImageClasses() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 136 static bool NonImageClassesVisitor(mirror::Class* c, void* arg) 137 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 138 139 // Verify unwanted classes removed. 140 void CheckNonImageClassesRemoved(); 141 static void CheckNonImageClassesRemovedCallback(mirror::Object* obj, void* arg) 142 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 143 144 // Lays out where the image objects will be at runtime. 145 void CalculateNewObjectOffsets(size_t oat_loaded_size, size_t oat_data_offset) 146 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 147 mirror::ObjectArray<mirror::Object>* CreateImageRoots() const 148 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 149 static void CalculateNewObjectOffsetsCallback(mirror::Object* obj, void* arg) 150 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 151 152 // Creates the contiguous image in memory and adjusts pointers. 153 void CopyAndFixupObjects(); 154 static void CopyAndFixupObjectsCallback(mirror::Object* obj, void* arg) 155 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 156 void FixupClass(const mirror::Class* orig, mirror::Class* copy) 157 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 158 void FixupMethod(const mirror::ArtMethod* orig, mirror::ArtMethod* copy) 159 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 160 void FixupObject(const mirror::Object* orig, mirror::Object* copy) 161 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 162 void FixupObjectArray(const mirror::ObjectArray<mirror::Object>* orig, 163 mirror::ObjectArray<mirror::Object>* copy) 164 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 165 void FixupInstanceFields(const mirror::Object* orig, mirror::Object* copy) 166 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 167 void FixupStaticFields(const mirror::Class* orig, mirror::Class* copy) 168 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 169 void FixupFields(const mirror::Object* orig, mirror::Object* copy, uint32_t ref_offsets, 170 bool is_static) 171 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 172 173 // Patches references in OatFile to expect runtime addresses. 174 void PatchOatCodeAndMethods() 175 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 176 void SetPatchLocation(const CompilerDriver::PatchInformation* patch, uint32_t value) 177 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 178 179 180 const CompilerDriver& compiler_driver_; 181 182 // Map of Object to where it will be at runtime. 183 SafeMap<const mirror::Object*, size_t> offsets_; 184 185 // oat file with code for this image 186 OatFile* oat_file_; 187 188 // Memory mapped for generating the image. 189 UniquePtr<MemMap> image_; 190 191 // Offset to the free space in image_. 192 size_t image_end_; 193 194 // Beginning target image address for the output image. 195 byte* image_begin_; 196 197 // Beginning target oat address for the pointers from the output image to its oat file. 198 const byte* oat_data_begin_; 199 200 // Image bitmap which lets us know where the objects inside of the image reside. 201 UniquePtr<gc::accounting::SpaceBitmap> image_bitmap_; 202 203 // Offset from oat_data_begin_ to the stubs. 204 uint32_t interpreter_to_interpreter_bridge_offset_; 205 uint32_t interpreter_to_compiled_code_bridge_offset_; 206 uint32_t jni_dlsym_lookup_offset_; 207 uint32_t portable_resolution_trampoline_offset_; 208 uint32_t portable_to_interpreter_bridge_offset_; 209 uint32_t quick_resolution_trampoline_offset_; 210 uint32_t quick_to_interpreter_bridge_offset_; 211 212 // DexCaches seen while scanning for fixing up CodeAndDirectMethods 213 std::set<mirror::DexCache*> dex_caches_; 214 }; 215 216 } // namespace art 217 218 #endif // ART_COMPILER_IMAGE_WRITER_H_ 219