blob: d32724cbb0c6060dd92fd5ce552fb60821415a91 [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
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070012#include "dex_cache.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070013#include "mem_map.h"
Brian Carlstrome24fa612011-09-29 00:53:55 -070014#include "oat_file.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070015#include "object.h"
16#include "os.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070017#include "space.h"
Elliott Hughese5448b52012-01-18 16:44:06 -080018#include "UniquePtr.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070019
20namespace art {
21
Brian Carlstrom4e777d42011-08-15 13:53:52 -070022// Write a Space built during compilation for use during execution.
Brian Carlstromdb4d5402011-08-09 12:18:28 -070023class ImageWriter {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070024 public:
Elliott Hughesff17f1f2012-01-24 18:12:29 -080025 explicit ImageWriter(const std::set<std::string>* image_classes)
Brian Carlstromae826982011-11-09 01:33:42 -080026 : source_space_(NULL), image_top_(0), image_base_(NULL), image_classes_(image_classes) {}
27
Elliott Hughes362f9bc2011-10-17 18:56:41 -070028 ~ImageWriter() {}
Brian Carlstromdb4d5402011-08-09 12:18:28 -070029
Brian Carlstromae826982011-11-09 01:33:42 -080030 bool Write(const char* image_filename,
31 uintptr_t image_base,
32 const std::string& oat_filename,
33 const std::string& strip_location_prefix);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070034 private:
35
Brian Carlstromae826982011-11-09 01:33:42 -080036 bool AllocMemory();
Brian Carlstromdb4d5402011-08-09 12:18:28 -070037
38 // we use the lock word to store the offset of the object in the image
Brian Carlstromc74255f2011-09-11 22:47:39 -070039 void AssignImageOffset(Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070040 DCHECK(object != NULL);
Elliott Hughescc607472011-10-17 15:34:11 -070041 DCHECK_EQ(object->monitor_, 0U); // should be no lock
Brian Carlstromc74255f2011-09-11 22:47:39 -070042 SetImageOffset(object, image_top_);
43 image_top_ += RoundUp(object->SizeOf(), 8); // 64-bit alignment
44 DCHECK_LT(image_top_, image_->GetLength());
45 }
46 static void SetImageOffset(Object* object, size_t offset) {
47 DCHECK(object != NULL);
48 // should be no lock (but it might be forward referenced interned string)
Elliott Hughesdbb40792011-11-18 17:05:22 -080049 DCHECK(object->monitor_ == 0 || object->GetClass()->IsStringClass());
Brian Carlstromdb4d5402011-08-09 12:18:28 -070050 DCHECK_NE(0U, offset);
Elliott Hughes5f791332011-09-15 17:45:30 -070051 object->monitor_ = offset;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070052 }
Brian Carlstromc74255f2011-09-11 22:47:39 -070053 static size_t IsImageOffsetAssigned(const Object* object) {
54 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070055 size_t offset = object->monitor_;
Brian Carlstromc74255f2011-09-11 22:47:39 -070056 return offset != 0U;
57 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070058 static size_t GetImageOffset(const Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070059 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070060 size_t offset = object->monitor_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070061 DCHECK_NE(0U, offset);
62 return offset;
63 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070064 static void ResetImageOffset(Object* object) {
65 DCHECK(object != NULL);
Elliott Hughescc607472011-10-17 15:34:11 -070066 DCHECK_NE(object->monitor_, 0U); // should be an offset
Elliott Hughes5f791332011-09-15 17:45:30 -070067 object->monitor_ = 0;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070068 }
69
Brian Carlstrom58ae9412011-10-04 00:56:06 -070070 bool InSourceSpace(const Object* object) const {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070071 DCHECK(source_space_ != NULL);
72 const byte* o = reinterpret_cast<const byte*>(object);
73 return (o >= source_space_->GetBase() && o < source_space_->GetLimit());
74 }
Brian Carlstrom58ae9412011-10-04 00:56:06 -070075 Object* GetImageAddress(const Object* object) const {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070076 if (object == NULL) {
77 return NULL;
78 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070079 // if object outside the relocating source_space_, assume unchanged
80 if (!InSourceSpace(object)) {
81 return const_cast<Object*>(object);
82 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070083 return reinterpret_cast<Object*>(image_base_ + GetImageOffset(object));
84 }
Brian Carlstrom58ae9412011-10-04 00:56:06 -070085 Object* GetLocalAddress(const Object* object) const {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070086 size_t offset = GetImageOffset(object);
87 byte* dst = image_->GetAddress() + offset;
88 return reinterpret_cast<Object*>(dst);
89 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070090
Brian Carlstromae826982011-11-09 01:33:42 -080091 const byte* GetOatAddress(uint32_t offset) const {
92 DCHECK_LT(offset, oat_file_->GetSize());
93 if (offset == 0) {
94 return NULL;
95 }
96 return oat_base_ + offset;
97 }
98
99 bool IsImageClass(const Class* klass);
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800100 void DumpImageClasses();
Brian Carlstromae826982011-11-09 01:33:42 -0800101
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
Elliott Hughese5448b52012-01-18 16:44:06 -0800147 typedef std::set<DexCache*> 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_