blob: b6b02f4e882afec20534eb54f00ac85b1014e1c7 [file] [log] [blame]
Brian Carlstromdb4d5402011-08-09 12:18:28 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
Brian Carlstrom4a289ed2011-08-16 17:17:49 -07003#ifndef ART_SRC_IMAGE_WRITER_H_
4#define ART_SRC_IMAGE_WRITER_H_
Brian Carlstromdb4d5402011-08-09 12:18:28 -07005
Brian Carlstromdb4d5402011-08-09 12:18:28 -07006#include <stdint.h>
7
Elliott Hughes90a33692011-08-30 13:27:07 -07008#include <cstddef>
Brian Carlstromae826982011-11-09 01:33:42 -08009#include <set>
10#include <string>
Elliott Hughes90a33692011-08-30 13:27:07 -070011
12#include "UniquePtr.h"
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070013#include "dex_cache.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070014#include "mem_map.h"
Brian Carlstrome24fa612011-09-29 00:53:55 -070015#include "oat_file.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070016#include "object.h"
17#include "os.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070018#include "space.h"
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -080019#include "unordered_set.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070020
21namespace art {
22
Brian Carlstrom4e777d42011-08-15 13:53:52 -070023// Write a Space built during compilation for use during execution.
Brian Carlstromdb4d5402011-08-09 12:18:28 -070024class ImageWriter {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070025 public:
Brian Carlstromae826982011-11-09 01:33:42 -080026 ImageWriter(const std::set<std::string>* image_classes)
27 : source_space_(NULL), image_top_(0), image_base_(NULL), image_classes_(image_classes) {}
28
Elliott Hughes362f9bc2011-10-17 18:56:41 -070029 ~ImageWriter() {}
Brian Carlstromdb4d5402011-08-09 12:18:28 -070030
Brian Carlstromae826982011-11-09 01:33:42 -080031 bool Write(const char* image_filename,
32 uintptr_t image_base,
33 const std::string& oat_filename,
34 const std::string& strip_location_prefix);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070035 private:
36
Brian Carlstromae826982011-11-09 01:33:42 -080037 bool AllocMemory();
Brian Carlstromdb4d5402011-08-09 12:18:28 -070038
39 // we use the lock word to store the offset of the object in the image
Brian Carlstromc74255f2011-09-11 22:47:39 -070040 void AssignImageOffset(Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070041 DCHECK(object != NULL);
Elliott Hughescc607472011-10-17 15:34:11 -070042 DCHECK_EQ(object->monitor_, 0U); // should be no lock
Brian Carlstromc74255f2011-09-11 22:47:39 -070043 SetImageOffset(object, image_top_);
44 image_top_ += RoundUp(object->SizeOf(), 8); // 64-bit alignment
45 DCHECK_LT(image_top_, image_->GetLength());
46 }
47 static void SetImageOffset(Object* object, size_t offset) {
48 DCHECK(object != NULL);
49 // should be no lock (but it might be forward referenced interned string)
Elliott Hughesdbb40792011-11-18 17:05:22 -080050 DCHECK(object->monitor_ == 0 || object->GetClass()->IsStringClass());
Brian Carlstromdb4d5402011-08-09 12:18:28 -070051 DCHECK_NE(0U, offset);
Elliott Hughes5f791332011-09-15 17:45:30 -070052 object->monitor_ = offset;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070053 }
Brian Carlstromc74255f2011-09-11 22:47:39 -070054 static size_t IsImageOffsetAssigned(const Object* object) {
55 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070056 size_t offset = object->monitor_;
Brian Carlstromc74255f2011-09-11 22:47:39 -070057 return offset != 0U;
58 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070059 static size_t GetImageOffset(const Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070060 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070061 size_t offset = object->monitor_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070062 DCHECK_NE(0U, offset);
63 return offset;
64 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070065 static void ResetImageOffset(Object* object) {
66 DCHECK(object != NULL);
Elliott Hughescc607472011-10-17 15:34:11 -070067 DCHECK_NE(object->monitor_, 0U); // should be an offset
Elliott Hughes5f791332011-09-15 17:45:30 -070068 object->monitor_ = 0;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070069 }
70
Brian Carlstrom58ae9412011-10-04 00:56:06 -070071 bool InSourceSpace(const Object* object) const {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070072 DCHECK(source_space_ != NULL);
73 const byte* o = reinterpret_cast<const byte*>(object);
74 return (o >= source_space_->GetBase() && o < source_space_->GetLimit());
75 }
Brian Carlstrom58ae9412011-10-04 00:56:06 -070076 Object* GetImageAddress(const Object* object) const {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070077 if (object == NULL) {
78 return NULL;
79 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070080 // if object outside the relocating source_space_, assume unchanged
81 if (!InSourceSpace(object)) {
82 return const_cast<Object*>(object);
83 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070084 return reinterpret_cast<Object*>(image_base_ + GetImageOffset(object));
85 }
Brian Carlstrom58ae9412011-10-04 00:56:06 -070086 Object* GetLocalAddress(const Object* object) const {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070087 size_t offset = GetImageOffset(object);
88 byte* dst = image_->GetAddress() + offset;
89 return reinterpret_cast<Object*>(dst);
90 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070091
Brian Carlstromae826982011-11-09 01:33:42 -080092 const byte* GetOatAddress(uint32_t offset) const {
93 DCHECK_LT(offset, oat_file_->GetSize());
94 if (offset == 0) {
95 return NULL;
96 }
97 return oat_base_ + offset;
98 }
99
100 bool IsImageClass(const Class* klass);
101
102 void PruneNonImageClasses();
103 static bool NonImageClassesVisitor(Class* c, void* arg);
104
105 void CheckNonImageClassesRemoved();
106 static void CheckNonImageClassesRemovedCallback(Object* obj, void* arg);
107
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700108 void CalculateNewObjectOffsets();
Brian Carlstrome24fa612011-09-29 00:53:55 -0700109 ObjectArray<Object>* CreateImageRoots() const;
Brian Carlstrom78128a62011-09-15 17:21:19 -0700110 static void CalculateNewObjectOffsetsCallback(Object* obj, void* arg);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700111
112 void CopyAndFixupObjects();
Brian Carlstrom78128a62011-09-15 17:21:19 -0700113 static void CopyAndFixupObjectsCallback(Object* obj, void* arg);
Brian Carlstrom4873d462011-08-21 15:23:39 -0700114 void FixupClass(const Class* orig, Class* copy);
115 void FixupMethod(const Method* orig, Method* copy);
Brian Carlstrom4873d462011-08-21 15:23:39 -0700116 void FixupObject(const Object* orig, Object* copy);
117 void FixupObjectArray(const ObjectArray<Object>* orig, ObjectArray<Object>* copy);
118 void FixupInstanceFields(const Object* orig, Object* copy);
119 void FixupStaticFields(const Class* orig, Class* copy);
120 void FixupFields(const Object* orig, Object* copy, uint32_t ref_offsets, bool is_static);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700121
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700122 void FixupDexCaches();
123 void FixupDexCache(const DexCache* orig, DexCache* copy);
124
Brian Carlstrome24fa612011-09-29 00:53:55 -0700125 // oat file with code for this image
126 UniquePtr<OatFile> oat_file_;
127
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700128 // Space we are writing objects from
129 const Space* source_space_;
130
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700131 // memory mapped for generating the image
Elliott Hughes90a33692011-08-30 13:27:07 -0700132 UniquePtr<MemMap> image_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700133
Brian Carlstrom4e777d42011-08-15 13:53:52 -0700134 // Offset to the free space in image_
135 size_t image_top_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700136
Brian Carlstrome24fa612011-09-29 00:53:55 -0700137 // Target image base address for the output image
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700138 byte* image_base_;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700139
Brian Carlstromae826982011-11-09 01:33:42 -0800140 // Set of classes to be include in the image, or NULL for all.
141 const std::set<std::string>* image_classes_;
142
Brian Carlstrome24fa612011-09-29 00:53:55 -0700143 // Target oat base address for the pointers from the output image to its oat file
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700144 const byte* oat_base_;
Brian Carlstrome24fa612011-09-29 00:53:55 -0700145
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700146 // DexCaches seen while scanning for fixing up CodeAndDirectMethods
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700147 typedef std::tr1::unordered_set<DexCache*, ObjectIdentityHash> Set;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700148 Set dex_caches_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700149};
150
151} // namespace art
152
Brian Carlstrom4a289ed2011-08-16 17:17:49 -0700153#endif // ART_SRC_IMAGE_WRITER_H_