blob: f62bea1286deb0bc123d1bc73a0a03630820f048 [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 Carlstromf5822582012-03-19 22:34:31 -070027#include "compiler.h"
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070028#include "dex_cache.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070029#include "mem_map.h"
Brian Carlstrome24fa612011-09-29 00:53:55 -070030#include "oat_file.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070031#include "object.h"
32#include "os.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070033#include "space.h"
Elliott Hughese5448b52012-01-18 16:44:06 -080034#include "UniquePtr.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070035
36namespace art {
37
Brian Carlstrom4e777d42011-08-15 13:53:52 -070038// Write a Space built during compilation for use during execution.
Brian Carlstromdb4d5402011-08-09 12:18:28 -070039class ImageWriter {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070040 public:
Elliott Hughesff17f1f2012-01-24 18:12:29 -080041 explicit ImageWriter(const std::set<std::string>* image_classes)
Ian Rogers30fab402012-01-23 15:43:46 -080042 : source_space_(NULL), image_end_(0), image_begin_(NULL), image_classes_(image_classes),
43 oat_begin_(NULL) {}
Brian Carlstromae826982011-11-09 01:33:42 -080044
Elliott Hughes362f9bc2011-10-17 18:56:41 -070045 ~ImageWriter() {}
Brian Carlstromdb4d5402011-08-09 12:18:28 -070046
Brian Carlstroma004aa92012-02-08 18:05:09 -080047 bool Write(const std::string& image_filename,
Ian Rogers30fab402012-01-23 15:43:46 -080048 uintptr_t image_begin,
Brian Carlstromae826982011-11-09 01:33:42 -080049 const std::string& oat_filename,
Brian Carlstromf5822582012-03-19 22:34:31 -070050 const std::string& oat_location,
51 const Compiler& compiler);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070052 private:
53
Brian Carlstromae826982011-11-09 01:33:42 -080054 bool AllocMemory();
Brian Carlstromdb4d5402011-08-09 12:18:28 -070055
56 // 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 }
Elliott Hughesb3bd5f02012-03-08 21:05:27 -080063
64 void SetImageOffset(Object* object, size_t offset) {
Brian Carlstromc74255f2011-09-11 22:47:39 -070065 DCHECK(object != NULL);
Elliott Hughesd9c67be2012-02-02 19:54:06 -080066 DCHECK_NE(offset, 0U);
67 DCHECK(!IsImageOffsetAssigned(object));
68 offsets_[object] = offset;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070069 }
Elliott Hughesb3bd5f02012-03-08 21:05:27 -080070
71 size_t IsImageOffsetAssigned(const Object* object) const {
Brian Carlstromc74255f2011-09-11 22:47:39 -070072 DCHECK(object != NULL);
Elliott Hughesd9c67be2012-02-02 19:54:06 -080073 return offsets_.find(object) != offsets_.end();
Brian Carlstromc74255f2011-09-11 22:47:39 -070074 }
Elliott Hughesb3bd5f02012-03-08 21:05:27 -080075
76 size_t GetImageOffset(const Object* object) const {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070077 DCHECK(object != NULL);
Elliott Hughesd9c67be2012-02-02 19:54:06 -080078 DCHECK(IsImageOffsetAssigned(object));
Elliott Hughesb3bd5f02012-03-08 21:05:27 -080079 return offsets_.find(object)->second;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070080 }
81
Brian Carlstrom58ae9412011-10-04 00:56:06 -070082 bool InSourceSpace(const Object* object) const {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070083 DCHECK(source_space_ != NULL);
Ian Rogers30fab402012-01-23 15:43:46 -080084 return source_space_->Contains(object);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070085 }
Elliott Hughesb3bd5f02012-03-08 21:05:27 -080086
Brian Carlstrom58ae9412011-10-04 00:56:06 -070087 Object* GetImageAddress(const Object* object) const {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070088 if (object == NULL) {
89 return NULL;
90 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070091 // if object outside the relocating source_space_, assume unchanged
92 if (!InSourceSpace(object)) {
93 return const_cast<Object*>(object);
94 }
Ian Rogers30fab402012-01-23 15:43:46 -080095 return reinterpret_cast<Object*>(image_begin_ + GetImageOffset(object));
Brian Carlstromdb4d5402011-08-09 12:18:28 -070096 }
Elliott Hughesb3bd5f02012-03-08 21:05:27 -080097
Brian Carlstrom58ae9412011-10-04 00:56:06 -070098 Object* GetLocalAddress(const Object* object) const {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070099 size_t offset = GetImageOffset(object);
Ian Rogers30fab402012-01-23 15:43:46 -0800100 byte* dst = image_->Begin() + offset;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700101 return reinterpret_cast<Object*>(dst);
102 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700103
Brian Carlstromae826982011-11-09 01:33:42 -0800104 const byte* GetOatAddress(uint32_t offset) const {
Ian Rogers30fab402012-01-23 15:43:46 -0800105 DCHECK_LT(offset, oat_file_->Size());
Brian Carlstromae826982011-11-09 01:33:42 -0800106 if (offset == 0) {
107 return NULL;
108 }
Ian Rogers30fab402012-01-23 15:43:46 -0800109 return oat_begin_ + offset;
Brian Carlstromae826982011-11-09 01:33:42 -0800110 }
111
112 bool IsImageClass(const Class* klass);
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800113 void DumpImageClasses();
Brian Carlstromae826982011-11-09 01:33:42 -0800114
Ian Rogersd418eda2012-01-30 12:14:28 -0800115 void ComputeLazyFieldsForImageClasses();
116 static bool ComputeLazyFieldsForClassesVisitor(Class* klass, void* arg);
117
Ian Rogersd1f1bf02012-02-26 16:59:20 -0800118 // Wire dex cache resolved strings to strings in the image to avoid runtime resolution
119 void ComputeEagerResolvedStrings();
120 static void ComputeEagerResolvedStringsCallback(Object* obj, void* arg);
121
Brian Carlstromae826982011-11-09 01:33:42 -0800122 void PruneNonImageClasses();
123 static bool NonImageClassesVisitor(Class* c, void* arg);
124
125 void CheckNonImageClassesRemoved();
126 static void CheckNonImageClassesRemovedCallback(Object* obj, void* arg);
127
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700128 void CalculateNewObjectOffsets();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700129 ObjectArray<Object>* CreateImageRoots() const;
Brian Carlstrom78128a62011-09-15 17:21:19 -0700130 static void CalculateNewObjectOffsetsCallback(Object* obj, void* arg);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700131
132 void CopyAndFixupObjects();
Brian Carlstrom78128a62011-09-15 17:21:19 -0700133 static void CopyAndFixupObjectsCallback(Object* obj, void* arg);
Brian Carlstrom4873d462011-08-21 15:23:39 -0700134 void FixupClass(const Class* orig, Class* copy);
135 void FixupMethod(const Method* orig, Method* copy);
Brian Carlstrom4873d462011-08-21 15:23:39 -0700136 void FixupObject(const Object* orig, Object* copy);
137 void FixupObjectArray(const ObjectArray<Object>* orig, ObjectArray<Object>* copy);
138 void FixupInstanceFields(const Object* orig, Object* copy);
139 void FixupStaticFields(const Class* orig, Class* copy);
140 void FixupFields(const Object* orig, Object* copy, uint32_t ref_offsets, bool is_static);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700141
Brian Carlstromf5822582012-03-19 22:34:31 -0700142 void PatchOatCodeAndMethods(const Compiler& compiler);
143 void SetPatchLocation(const Compiler::PatchInformation* patch, uint32_t value);
144
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800145 std::map<const Object*, size_t> offsets_;
146
Brian Carlstrome24fa612011-09-29 00:53:55 -0700147 // oat file with code for this image
Brian Carlstromf5822582012-03-19 22:34:31 -0700148 OatFile* oat_file_;
Brian Carlstrome24fa612011-09-29 00:53:55 -0700149
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700150 // Space we are writing objects from
151 const Space* source_space_;
152
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700153 // memory mapped for generating the image
Elliott Hughes90a33692011-08-30 13:27:07 -0700154 UniquePtr<MemMap> image_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700155
Brian Carlstrom4e777d42011-08-15 13:53:52 -0700156 // Offset to the free space in image_
Ian Rogers30fab402012-01-23 15:43:46 -0800157 size_t image_end_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700158
Ian Rogers30fab402012-01-23 15:43:46 -0800159 // Beginning target image address for the output image
160 byte* image_begin_;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700161
Brian Carlstromae826982011-11-09 01:33:42 -0800162 // Set of classes to be include in the image, or NULL for all.
163 const std::set<std::string>* image_classes_;
164
Ian Rogers30fab402012-01-23 15:43:46 -0800165 // Beginning target oat address for the pointers from the output image to its oat file
166 const byte* oat_begin_;
Brian Carlstrome24fa612011-09-29 00:53:55 -0700167
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700168 // DexCaches seen while scanning for fixing up CodeAndDirectMethods
Elliott Hughese5448b52012-01-18 16:44:06 -0800169 typedef std::set<DexCache*> Set;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700170 Set dex_caches_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700171};
172
173} // namespace art
174
Brian Carlstrom4a289ed2011-08-16 17:17:49 -0700175#endif // ART_SRC_IMAGE_WRITER_H_