blob: c1480ff3299d565e4a5f227eb5965e24fa84443e [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"
13#include "object.h"
14#include "os.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070015#include "space.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070016
17namespace art {
18
Brian Carlstrom4e777d42011-08-15 13:53:52 -070019// Write a Space built during compilation for use during execution.
Brian Carlstromdb4d5402011-08-09 12:18:28 -070020class ImageWriter {
21
22 public:
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070023 ImageWriter() : source_space_(NULL), image_top_(0), image_base_(NULL) {};
24 bool Write(const char* filename, uintptr_t image_base);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070025 ~ImageWriter() {};
26
27 private:
28
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070029 bool Init();
Brian Carlstromdb4d5402011-08-09 12:18:28 -070030
31 // we use the lock word to store the offset of the object in the image
Brian Carlstromc74255f2011-09-11 22:47:39 -070032 void AssignImageOffset(Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070033 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070034 DCHECK(object->monitor_ == 0); // should be no lock
Brian Carlstromc74255f2011-09-11 22:47:39 -070035 SetImageOffset(object, image_top_);
36 image_top_ += RoundUp(object->SizeOf(), 8); // 64-bit alignment
37 DCHECK_LT(image_top_, image_->GetLength());
38 }
39 static void SetImageOffset(Object* object, size_t offset) {
40 DCHECK(object != NULL);
41 // should be no lock (but it might be forward referenced interned string)
Elliott Hughes5f791332011-09-15 17:45:30 -070042 DCHECK(object->monitor_ == 0 || object->IsString());
Brian Carlstromdb4d5402011-08-09 12:18:28 -070043 DCHECK_NE(0U, offset);
Elliott Hughes5f791332011-09-15 17:45:30 -070044 object->monitor_ = offset;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070045 }
Brian Carlstromc74255f2011-09-11 22:47:39 -070046 static size_t IsImageOffsetAssigned(const Object* object) {
47 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070048 size_t offset = object->monitor_;
Brian Carlstromc74255f2011-09-11 22:47:39 -070049 return offset != 0U;
50 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070051 static size_t GetImageOffset(const Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070052 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070053 size_t offset = object->monitor_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070054 DCHECK_NE(0U, offset);
55 return offset;
56 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070057 static void ResetImageOffset(Object* object) {
58 DCHECK(object != NULL);
Elliott Hughes5f791332011-09-15 17:45:30 -070059 DCHECK(object->monitor_ != 0); // should be an offset
60 object->monitor_ = 0;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070061 }
62
63 bool InSourceSpace(const Object* object) {
64 DCHECK(source_space_ != NULL);
65 const byte* o = reinterpret_cast<const byte*>(object);
66 return (o >= source_space_->GetBase() && o < source_space_->GetLimit());
67 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070068 Object* GetImageAddress(const Object* object) {
69 if (object == NULL) {
70 return NULL;
71 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070072 // if object outside the relocating source_space_, assume unchanged
73 if (!InSourceSpace(object)) {
74 return const_cast<Object*>(object);
75 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070076 return reinterpret_cast<Object*>(image_base_ + GetImageOffset(object));
77 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070078 Object* GetLocalAddress(const Object* object) {
79 size_t offset = GetImageOffset(object);
80 byte* dst = image_->GetAddress() + offset;
81 return reinterpret_cast<Object*>(dst);
82 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070083
84 void CalculateNewObjectOffsets();
Brian Carlstrom78128a62011-09-15 17:21:19 -070085 static void CalculateNewObjectOffsetsCallback(Object* obj, void* arg);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070086
87 void CopyAndFixupObjects();
Brian Carlstrom78128a62011-09-15 17:21:19 -070088 static void CopyAndFixupObjectsCallback(Object* obj, void* arg);
Brian Carlstrom4873d462011-08-21 15:23:39 -070089 void FixupClass(const Class* orig, Class* copy);
90 void FixupMethod(const Method* orig, Method* copy);
Brian Carlstrom4873d462011-08-21 15:23:39 -070091 void FixupObject(const Object* orig, Object* copy);
92 void FixupObjectArray(const ObjectArray<Object>* orig, ObjectArray<Object>* copy);
93 void FixupInstanceFields(const Object* orig, Object* copy);
94 void FixupStaticFields(const Class* orig, Class* copy);
95 void FixupFields(const Object* orig, Object* copy, uint32_t ref_offsets, bool is_static);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070096
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070097 void FixupDexCaches();
98 void FixupDexCache(const DexCache* orig, DexCache* copy);
99
100 // Space we are writing objects from
101 const Space* source_space_;
102
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700103 // memory mapped for generating the image
Elliott Hughes90a33692011-08-30 13:27:07 -0700104 UniquePtr<MemMap> image_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700105
Brian Carlstrom4e777d42011-08-15 13:53:52 -0700106 // Offset to the free space in image_
107 size_t image_top_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700108
109 // Target base address for the output image
110 byte* image_base_;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700111
112 // DexCaches seen while scanning for fixing up CodeAndDirectMethods
113 typedef std::tr1::unordered_set<DexCache*, DexCacheHash> Set;
114 Set dex_caches_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700115};
116
117} // namespace art
118
Brian Carlstrom4a289ed2011-08-16 17:17:49 -0700119#endif // ART_SRC_IMAGE_WRITER_H_