blob: 9d46c06e5c725d7967fb288a6c29482d8dfe382b [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
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 */
Brian Carlstromdb4d5402011-08-09 12:18:28 -070016
Brian Carlstrom4a289ed2011-08-16 17:17:49 -070017#ifndef ART_SRC_IMAGE_WRITER_H_
18#define ART_SRC_IMAGE_WRITER_H_
Brian Carlstromdb4d5402011-08-09 12:18:28 -070019
Brian Carlstromdb4d5402011-08-09 12:18:28 -070020#include <stdint.h>
21
Elliott Hughes90a33692011-08-30 13:27:07 -070022#include <cstddef>
Elliott Hughesd9c67be2012-02-02 19:54:06 -080023#include <map>
Brian Carlstromae826982011-11-09 01:33:42 -080024#include <set>
25#include <string>
Elliott Hughes90a33692011-08-30 13:27:07 -070026
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070027#include "dex_cache.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070028#include "mem_map.h"
Brian Carlstrome24fa612011-09-29 00:53:55 -070029#include "oat_file.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070030#include "object.h"
31#include "os.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070032#include "space.h"
Elliott Hughese5448b52012-01-18 16:44:06 -080033#include "UniquePtr.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070034
35namespace art {
36
Brian Carlstrom4e777d42011-08-15 13:53:52 -070037// Write a Space built during compilation for use during execution.
Brian Carlstromdb4d5402011-08-09 12:18:28 -070038class ImageWriter {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070039 public:
Elliott Hughesff17f1f2012-01-24 18:12:29 -080040 explicit ImageWriter(const std::set<std::string>* image_classes)
Ian Rogers30fab402012-01-23 15:43:46 -080041 : source_space_(NULL), image_end_(0), image_begin_(NULL), image_classes_(image_classes),
42 oat_begin_(NULL) {}
Brian Carlstromae826982011-11-09 01:33:42 -080043
Elliott Hughes362f9bc2011-10-17 18:56:41 -070044 ~ImageWriter() {}
Brian Carlstromdb4d5402011-08-09 12:18:28 -070045
Brian Carlstroma004aa92012-02-08 18:05:09 -080046 bool Write(const std::string& image_filename,
Ian Rogers30fab402012-01-23 15:43:46 -080047 uintptr_t image_begin,
Brian Carlstromae826982011-11-09 01:33:42 -080048 const std::string& oat_filename,
Brian Carlstroma004aa92012-02-08 18:05:09 -080049 const std::string& oat_location);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070050 private:
51
Brian Carlstromae826982011-11-09 01:33:42 -080052 bool AllocMemory();
Brian Carlstromdb4d5402011-08-09 12:18:28 -070053
Elliott Hughesd9c67be2012-02-02 19:54:06 -080054 static std::map<const Object*, size_t> offsets_;
55
Brian Carlstromdb4d5402011-08-09 12:18:28 -070056 // we use the lock word to store the offset of the object in the image
Brian Carlstromc74255f2011-09-11 22:47:39 -070057 void AssignImageOffset(Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070058 DCHECK(object != NULL);
Ian Rogers30fab402012-01-23 15:43:46 -080059 SetImageOffset(object, image_end_);
60 image_end_ += RoundUp(object->SizeOf(), 8); // 64-bit alignment
61 DCHECK_LT(image_end_, image_->Size());
Brian Carlstromc74255f2011-09-11 22:47:39 -070062 }
63 static void SetImageOffset(Object* object, size_t offset) {
64 DCHECK(object != NULL);
Elliott Hughesd9c67be2012-02-02 19:54:06 -080065 DCHECK_NE(offset, 0U);
66 DCHECK(!IsImageOffsetAssigned(object));
67 offsets_[object] = offset;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070068 }
Brian Carlstromc74255f2011-09-11 22:47:39 -070069 static size_t IsImageOffsetAssigned(const Object* object) {
70 DCHECK(object != NULL);
Elliott Hughesd9c67be2012-02-02 19:54:06 -080071 return offsets_.find(object) != offsets_.end();
Brian Carlstromc74255f2011-09-11 22:47:39 -070072 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070073 static size_t GetImageOffset(const Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070074 DCHECK(object != NULL);
Elliott Hughesd9c67be2012-02-02 19:54:06 -080075 DCHECK(IsImageOffsetAssigned(object));
76 return offsets_[object];
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070077 }
78
Brian Carlstrom58ae9412011-10-04 00:56:06 -070079 bool InSourceSpace(const Object* object) const {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070080 DCHECK(source_space_ != NULL);
Ian Rogers30fab402012-01-23 15:43:46 -080081 return source_space_->Contains(object);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070082 }
Brian Carlstrom58ae9412011-10-04 00:56:06 -070083 Object* GetImageAddress(const Object* object) const {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070084 if (object == NULL) {
85 return NULL;
86 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070087 // if object outside the relocating source_space_, assume unchanged
88 if (!InSourceSpace(object)) {
89 return const_cast<Object*>(object);
90 }
Ian Rogers30fab402012-01-23 15:43:46 -080091 return reinterpret_cast<Object*>(image_begin_ + GetImageOffset(object));
Brian Carlstromdb4d5402011-08-09 12:18:28 -070092 }
Brian Carlstrom58ae9412011-10-04 00:56:06 -070093 Object* GetLocalAddress(const Object* object) const {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070094 size_t offset = GetImageOffset(object);
Ian Rogers30fab402012-01-23 15:43:46 -080095 byte* dst = image_->Begin() + offset;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070096 return reinterpret_cast<Object*>(dst);
97 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070098
Brian Carlstromae826982011-11-09 01:33:42 -080099 const byte* GetOatAddress(uint32_t offset) const {
Ian Rogers30fab402012-01-23 15:43:46 -0800100 DCHECK_LT(offset, oat_file_->Size());
Brian Carlstromae826982011-11-09 01:33:42 -0800101 if (offset == 0) {
102 return NULL;
103 }
Ian Rogers30fab402012-01-23 15:43:46 -0800104 return oat_begin_ + offset;
Brian Carlstromae826982011-11-09 01:33:42 -0800105 }
106
107 bool IsImageClass(const Class* klass);
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800108 void DumpImageClasses();
Brian Carlstromae826982011-11-09 01:33:42 -0800109
Ian Rogersd418eda2012-01-30 12:14:28 -0800110 void ComputeLazyFieldsForImageClasses();
111 static bool ComputeLazyFieldsForClassesVisitor(Class* klass, void* arg);
112
Ian Rogersd1f1bf02012-02-26 16:59:20 -0800113 // Wire dex cache resolved strings to strings in the image to avoid runtime resolution
114 void ComputeEagerResolvedStrings();
115 static void ComputeEagerResolvedStringsCallback(Object* obj, void* arg);
116
Brian Carlstromae826982011-11-09 01:33:42 -0800117 void PruneNonImageClasses();
118 static bool NonImageClassesVisitor(Class* c, void* arg);
119
120 void CheckNonImageClassesRemoved();
121 static void CheckNonImageClassesRemovedCallback(Object* obj, void* arg);
122
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700123 void CalculateNewObjectOffsets();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700124 ObjectArray<Object>* CreateImageRoots() const;
Brian Carlstrom78128a62011-09-15 17:21:19 -0700125 static void CalculateNewObjectOffsetsCallback(Object* obj, void* arg);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700126
127 void CopyAndFixupObjects();
Brian Carlstrom78128a62011-09-15 17:21:19 -0700128 static void CopyAndFixupObjectsCallback(Object* obj, void* arg);
Brian Carlstrom4873d462011-08-21 15:23:39 -0700129 void FixupClass(const Class* orig, Class* copy);
130 void FixupMethod(const Method* orig, Method* copy);
Brian Carlstrom4873d462011-08-21 15:23:39 -0700131 void FixupObject(const Object* orig, Object* copy);
132 void FixupObjectArray(const ObjectArray<Object>* orig, ObjectArray<Object>* copy);
133 void FixupInstanceFields(const Object* orig, Object* copy);
134 void FixupStaticFields(const Class* orig, Class* copy);
135 void FixupFields(const Object* orig, Object* copy, uint32_t ref_offsets, bool is_static);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700136
Brian Carlstrome24fa612011-09-29 00:53:55 -0700137 // oat file with code for this image
138 UniquePtr<OatFile> oat_file_;
139
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700140 // Space we are writing objects from
141 const Space* source_space_;
142
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700143 // memory mapped for generating the image
Elliott Hughes90a33692011-08-30 13:27:07 -0700144 UniquePtr<MemMap> image_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700145
Brian Carlstrom4e777d42011-08-15 13:53:52 -0700146 // Offset to the free space in image_
Ian Rogers30fab402012-01-23 15:43:46 -0800147 size_t image_end_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700148
Ian Rogers30fab402012-01-23 15:43:46 -0800149 // Beginning target image address for the output image
150 byte* image_begin_;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700151
Brian Carlstromae826982011-11-09 01:33:42 -0800152 // Set of classes to be include in the image, or NULL for all.
153 const std::set<std::string>* image_classes_;
154
Ian Rogers30fab402012-01-23 15:43:46 -0800155 // Beginning target oat address for the pointers from the output image to its oat file
156 const byte* oat_begin_;
Brian Carlstrome24fa612011-09-29 00:53:55 -0700157
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700158 // DexCaches seen while scanning for fixing up CodeAndDirectMethods
Elliott Hughese5448b52012-01-18 16:44:06 -0800159 typedef std::set<DexCache*> Set;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700160 Set dex_caches_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700161};
162
163} // namespace art
164
Brian Carlstrom4a289ed2011-08-16 17:17:49 -0700165#endif // ART_SRC_IMAGE_WRITER_H_