/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ART_SRC_IMAGE_WRITER_H_ #define ART_SRC_IMAGE_WRITER_H_ #include #include #include #include #include #include "compiler.h" #include "dex_cache.h" #include "mem_map.h" #include "oat_file.h" #include "object.h" #include "os.h" #include "space.h" #include "UniquePtr.h" namespace art { // Write a Space built during compilation for use during execution. class ImageWriter { public: explicit ImageWriter(const std::set* image_classes) : source_space_(NULL), image_end_(0), image_begin_(NULL), image_classes_(image_classes), oat_begin_(NULL) {} ~ImageWriter() {} bool Write(const std::string& image_filename, uintptr_t image_begin, const std::string& oat_filename, const std::string& oat_location, const Compiler& compiler); private: bool AllocMemory(); // we use the lock word to store the offset of the object in the image void AssignImageOffset(Object* object) { DCHECK(object != NULL); SetImageOffset(object, image_end_); image_end_ += RoundUp(object->SizeOf(), 8); // 64-bit alignment DCHECK_LT(image_end_, image_->Size()); } void SetImageOffset(Object* object, size_t offset) { DCHECK(object != NULL); DCHECK_NE(offset, 0U); DCHECK(!IsImageOffsetAssigned(object)); offsets_[object] = offset; } size_t IsImageOffsetAssigned(const Object* object) const { DCHECK(object != NULL); return offsets_.find(object) != offsets_.end(); } size_t GetImageOffset(const Object* object) const { DCHECK(object != NULL); DCHECK(IsImageOffsetAssigned(object)); return offsets_.find(object)->second; } bool InSourceSpace(const Object* object) const { DCHECK(source_space_ != NULL); return source_space_->Contains(object); } Object* GetImageAddress(const Object* object) const { if (object == NULL) { return NULL; } // if object outside the relocating source_space_, assume unchanged if (!InSourceSpace(object)) { return const_cast(object); } return reinterpret_cast(image_begin_ + GetImageOffset(object)); } Object* GetLocalAddress(const Object* object) const { size_t offset = GetImageOffset(object); byte* dst = image_->Begin() + offset; return reinterpret_cast(dst); } const byte* GetOatAddress(uint32_t offset) const { DCHECK_LT(offset, oat_file_->Size()); if (offset == 0) { return NULL; } return oat_begin_ + offset; } bool IsImageClass(const Class* klass); void DumpImageClasses(); void ComputeLazyFieldsForImageClasses(); static bool ComputeLazyFieldsForClassesVisitor(Class* klass, void* arg); // Wire dex cache resolved strings to strings in the image to avoid runtime resolution void ComputeEagerResolvedStrings(); static void ComputeEagerResolvedStringsCallback(Object* obj, void* arg); void PruneNonImageClasses(); static bool NonImageClassesVisitor(Class* c, void* arg); void CheckNonImageClassesRemoved(); static void CheckNonImageClassesRemovedCallback(Object* obj, void* arg); void CalculateNewObjectOffsets(); ObjectArray* CreateImageRoots() const; static void CalculateNewObjectOffsetsCallback(Object* obj, void* arg); void CopyAndFixupObjects(); static void CopyAndFixupObjectsCallback(Object* obj, void* arg); void FixupClass(const Class* orig, Class* copy); void FixupMethod(const Method* orig, Method* copy); void FixupObject(const Object* orig, Object* copy); void FixupObjectArray(const ObjectArray* orig, ObjectArray* copy); void FixupInstanceFields(const Object* orig, Object* copy); void FixupStaticFields(const Class* orig, Class* copy); void FixupFields(const Object* orig, Object* copy, uint32_t ref_offsets, bool is_static); void PatchOatCodeAndMethods(const Compiler& compiler); void SetPatchLocation(const Compiler::PatchInformation* patch, uint32_t value); std::map offsets_; // oat file with code for this image OatFile* oat_file_; // Space we are writing objects from const Space* source_space_; // memory mapped for generating the image UniquePtr image_; // Offset to the free space in image_ size_t image_end_; // Beginning target image address for the output image byte* image_begin_; // Set of classes to be include in the image, or NULL for all. const std::set* image_classes_; // Beginning target oat address for the pointers from the output image to its oat file const byte* oat_begin_; // DexCaches seen while scanning for fixing up CodeAndDirectMethods typedef std::set Set; Set dex_caches_; }; } // namespace art #endif // ART_SRC_IMAGE_WRITER_H_