blob: ec17ebffcd0501db0e206ff18773b075d7b696a2 [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 {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070022 public:
Elliott Hughes362f9bc2011-10-17 18:56:41 -070023 ImageWriter() : source_space_(NULL), image_top_(0), image_base_(NULL) {}
Brian Carlstrome24fa612011-09-29 00:53:55 -070024 bool Write(const char* image_filename, uintptr_t image_base,
25 const std::string& oat_filename, const std::string& strip_location_prefix);
Elliott Hughes362f9bc2011-10-17 18:56:41 -070026 ~ImageWriter() {}
Brian Carlstromdb4d5402011-08-09 12:18:28 -070027
28 private:
29
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070030 bool Init();
Brian Carlstromdb4d5402011-08-09 12:18:28 -070031
32 // we use the lock word to store the offset of the object in the image
Brian Carlstromc74255f2011-09-11 22:47:39 -070033 void AssignImageOffset(Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070034 DCHECK(object != NULL);
Elliott Hughescc607472011-10-17 15:34:11 -070035 DCHECK_EQ(object->monitor_, 0U); // should be no lock
Brian Carlstromc74255f2011-09-11 22:47:39 -070036 SetImageOffset(object, image_top_);
37 image_top_ += RoundUp(object->SizeOf(), 8); // 64-bit alignment
38 DCHECK_LT(image_top_, image_->GetLength());
39 }
40 static void SetImageOffset(Object* object, size_t offset) {
41 DCHECK(object != NULL);
42 // should be no lock (but it might be forward referenced interned string)
Elliott Hughesdbb40792011-11-18 17:05:22 -080043 DCHECK(object->monitor_ == 0 || object->GetClass()->IsStringClass());
Brian Carlstromdb4d5402011-08-09 12:18:28 -070044 DCHECK_NE(0U, offset);
Elliott Hughes5f791332011-09-15 17:45:30 -070045 object->monitor_ = offset;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070046 }
Brian Carlstromc74255f2011-09-11 22:47:39 -070047 static size_t IsImageOffsetAssigned(const Object* object) {
48 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070049 size_t offset = object->monitor_;
Brian Carlstromc74255f2011-09-11 22:47:39 -070050 return offset != 0U;
51 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070052 static size_t GetImageOffset(const Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070053 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070054 size_t offset = object->monitor_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070055 DCHECK_NE(0U, offset);
56 return offset;
57 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070058 static void ResetImageOffset(Object* object) {
59 DCHECK(object != NULL);
Elliott Hughescc607472011-10-17 15:34:11 -070060 DCHECK_NE(object->monitor_, 0U); // should be an offset
Elliott Hughes5f791332011-09-15 17:45:30 -070061 object->monitor_ = 0;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070062 }
63
Brian Carlstrom58ae9412011-10-04 00:56:06 -070064 bool InSourceSpace(const Object* object) const {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070065 DCHECK(source_space_ != NULL);
66 const byte* o = reinterpret_cast<const byte*>(object);
67 return (o >= source_space_->GetBase() && o < source_space_->GetLimit());
68 }
Brian Carlstrom58ae9412011-10-04 00:56:06 -070069 Object* GetImageAddress(const Object* object) const {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070070 if (object == NULL) {
71 return NULL;
72 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070073 // if object outside the relocating source_space_, assume unchanged
74 if (!InSourceSpace(object)) {
75 return const_cast<Object*>(object);
76 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070077 return reinterpret_cast<Object*>(image_base_ + GetImageOffset(object));
78 }
Brian Carlstrom58ae9412011-10-04 00:56:06 -070079 Object* GetLocalAddress(const Object* object) const {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070080 size_t offset = GetImageOffset(object);
81 byte* dst = image_->GetAddress() + offset;
82 return reinterpret_cast<Object*>(dst);
83 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070084
85 void CalculateNewObjectOffsets();
Brian Carlstrome24fa612011-09-29 00:53:55 -070086 ObjectArray<Object>* CreateImageRoots() const;
Brian Carlstrom78128a62011-09-15 17:21:19 -070087 static void CalculateNewObjectOffsetsCallback(Object* obj, void* arg);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070088
89 void CopyAndFixupObjects();
Brian Carlstrom78128a62011-09-15 17:21:19 -070090 static void CopyAndFixupObjectsCallback(Object* obj, void* arg);
Brian Carlstrom4873d462011-08-21 15:23:39 -070091 void FixupClass(const Class* orig, Class* copy);
92 void FixupMethod(const Method* orig, Method* copy);
Brian Carlstrom4873d462011-08-21 15:23:39 -070093 void FixupObject(const Object* orig, Object* copy);
94 void FixupObjectArray(const ObjectArray<Object>* orig, ObjectArray<Object>* copy);
95 void FixupInstanceFields(const Object* orig, Object* copy);
96 void FixupStaticFields(const Class* orig, Class* copy);
97 void FixupFields(const Object* orig, Object* copy, uint32_t ref_offsets, bool is_static);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070098
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070099 void FixupDexCaches();
100 void FixupDexCache(const DexCache* orig, DexCache* copy);
101
Brian Carlstrome24fa612011-09-29 00:53:55 -0700102 // oat file with code for this image
103 UniquePtr<OatFile> oat_file_;
104
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700105 // Space we are writing objects from
106 const Space* source_space_;
107
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700108 // memory mapped for generating the image
Elliott Hughes90a33692011-08-30 13:27:07 -0700109 UniquePtr<MemMap> image_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700110
Brian Carlstrom4e777d42011-08-15 13:53:52 -0700111 // Offset to the free space in image_
112 size_t image_top_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700113
Brian Carlstrome24fa612011-09-29 00:53:55 -0700114 // Target image base address for the output image
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700115 byte* image_base_;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700116
Brian Carlstrome24fa612011-09-29 00:53:55 -0700117 // Target oat base address for the pointers from the output image to its oat file
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700118 const byte* oat_base_;
Brian Carlstrome24fa612011-09-29 00:53:55 -0700119
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700120 // DexCaches seen while scanning for fixing up CodeAndDirectMethods
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700121 typedef std::tr1::unordered_set<DexCache*, ObjectIdentityHash> Set;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700122 Set dex_caches_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700123};
124
125} // namespace art
126
Brian Carlstrom4a289ed2011-08-16 17:17:49 -0700127#endif // ART_SRC_IMAGE_WRITER_H_