blob: 3c17538006b2c921d76b73aea8cf962f218930ff [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>
9
10#include "UniquePtr.h"
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070011#include "dex_cache.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070012#include "mem_map.h"
Brian Carlstrome24fa612011-09-29 00:53:55 -070013#include "oat_file.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070014#include "object.h"
15#include "os.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070016#include "space.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070017
18namespace art {
19
Brian Carlstrom4e777d42011-08-15 13:53:52 -070020// Write a Space built during compilation for use during execution.
Brian Carlstromdb4d5402011-08-09 12:18:28 -070021class ImageWriter {
22
23 public:
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070024 ImageWriter() : source_space_(NULL), image_top_(0), image_base_(NULL) {};
Brian Carlstrome24fa612011-09-29 00:53:55 -070025 bool Write(const char* image_filename, uintptr_t image_base,
26 const std::string& oat_filename, const std::string& strip_location_prefix);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070027 ~ImageWriter() {};
28
29 private:
30
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070031 bool Init();
Brian Carlstromdb4d5402011-08-09 12:18:28 -070032
33 // we use the lock word to store the offset of the object in the image
Brian Carlstromc74255f2011-09-11 22:47:39 -070034 void AssignImageOffset(Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070035 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070036 DCHECK(object->monitor_ == 0); // should be no lock
Brian Carlstromc74255f2011-09-11 22:47:39 -070037 SetImageOffset(object, image_top_);
38 image_top_ += RoundUp(object->SizeOf(), 8); // 64-bit alignment
39 DCHECK_LT(image_top_, image_->GetLength());
40 }
41 static void SetImageOffset(Object* object, size_t offset) {
42 DCHECK(object != NULL);
43 // should be no lock (but it might be forward referenced interned string)
Elliott Hughes5f791332011-09-15 17:45:30 -070044 DCHECK(object->monitor_ == 0 || object->IsString());
Brian Carlstromdb4d5402011-08-09 12:18:28 -070045 DCHECK_NE(0U, offset);
Elliott Hughes5f791332011-09-15 17:45:30 -070046 object->monitor_ = offset;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070047 }
Brian Carlstromc74255f2011-09-11 22:47:39 -070048 static size_t IsImageOffsetAssigned(const Object* object) {
49 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070050 size_t offset = object->monitor_;
Brian Carlstromc74255f2011-09-11 22:47:39 -070051 return offset != 0U;
52 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070053 static size_t GetImageOffset(const Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070054 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070055 size_t offset = object->monitor_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070056 DCHECK_NE(0U, offset);
57 return offset;
58 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070059 static void ResetImageOffset(Object* object) {
60 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070061 DCHECK(object->monitor_ != 0); // should be an offset
62 object->monitor_ = 0;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070063 }
64
Brian Carlstrom58ae9412011-10-04 00:56:06 -070065 bool InSourceSpace(const Object* object) const {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070066 DCHECK(source_space_ != NULL);
67 const byte* o = reinterpret_cast<const byte*>(object);
68 return (o >= source_space_->GetBase() && o < source_space_->GetLimit());
69 }
Brian Carlstrom58ae9412011-10-04 00:56:06 -070070 Object* GetImageAddress(const Object* object) const {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070071 if (object == NULL) {
72 return NULL;
73 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070074 // if object outside the relocating source_space_, assume unchanged
75 if (!InSourceSpace(object)) {
76 return const_cast<Object*>(object);
77 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070078 return reinterpret_cast<Object*>(image_base_ + GetImageOffset(object));
79 }
Brian Carlstrom58ae9412011-10-04 00:56:06 -070080 Object* GetLocalAddress(const Object* object) const {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070081 size_t offset = GetImageOffset(object);
82 byte* dst = image_->GetAddress() + offset;
83 return reinterpret_cast<Object*>(dst);
84 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070085
86 void CalculateNewObjectOffsets();
Brian Carlstrome24fa612011-09-29 00:53:55 -070087 ObjectArray<Object>* CreateImageRoots() const;
Brian Carlstrom78128a62011-09-15 17:21:19 -070088 static void CalculateNewObjectOffsetsCallback(Object* obj, void* arg);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070089
90 void CopyAndFixupObjects();
Brian Carlstrom78128a62011-09-15 17:21:19 -070091 static void CopyAndFixupObjectsCallback(Object* obj, void* arg);
Brian Carlstrom4873d462011-08-21 15:23:39 -070092 void FixupClass(const Class* orig, Class* copy);
93 void FixupMethod(const Method* orig, Method* copy);
Brian Carlstrom4873d462011-08-21 15:23:39 -070094 void FixupObject(const Object* orig, Object* copy);
95 void FixupObjectArray(const ObjectArray<Object>* orig, ObjectArray<Object>* copy);
96 void FixupInstanceFields(const Object* orig, Object* copy);
97 void FixupStaticFields(const Class* orig, Class* copy);
98 void FixupFields(const Object* orig, Object* copy, uint32_t ref_offsets, bool is_static);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070099
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700100 void FixupDexCaches();
101 void FixupDexCache(const DexCache* orig, DexCache* copy);
102
Brian Carlstrome24fa612011-09-29 00:53:55 -0700103 // oat file with code for this image
104 UniquePtr<OatFile> oat_file_;
105
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700106 // Space we are writing objects from
107 const Space* source_space_;
108
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700109 // memory mapped for generating the image
Elliott Hughes90a33692011-08-30 13:27:07 -0700110 UniquePtr<MemMap> image_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700111
Brian Carlstrom4e777d42011-08-15 13:53:52 -0700112 // Offset to the free space in image_
113 size_t image_top_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700114
Brian Carlstrome24fa612011-09-29 00:53:55 -0700115 // Target image base address for the output image
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700116 byte* image_base_;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700117
Brian Carlstrome24fa612011-09-29 00:53:55 -0700118 // Target oat base address for the pointers from the output image to its oat file
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700119 const byte* oat_base_;
Brian Carlstrome24fa612011-09-29 00:53:55 -0700120
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700121 // DexCaches seen while scanning for fixing up CodeAndDirectMethods
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700122 typedef std::tr1::unordered_set<DexCache*, ObjectIdentityHash> Set;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700123 Set dex_caches_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700124};
125
126} // namespace art
127
Brian Carlstrom4a289ed2011-08-16 17:17:49 -0700128#endif // ART_SRC_IMAGE_WRITER_H_