blob: 3352adbde91d9c67e1928aecb9c9f281c87202af [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 Carlstrom69b15fb2011-09-03 12:25:21 -070032 static void SetImageOffset(Object* object, size_t offset) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070033 DCHECK(object != NULL);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -070034 DCHECK(object->GetMonitor() == NULL); // should be no lock
Brian Carlstromdb4d5402011-08-09 12:18:28 -070035 DCHECK_NE(0U, offset);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -070036 object->SetMonitor(reinterpret_cast<Monitor*>(offset));
Brian Carlstromdb4d5402011-08-09 12:18:28 -070037 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070038 static size_t GetImageOffset(const Object* object) {
Brian Carlstromdb4d5402011-08-09 12:18:28 -070039 DCHECK(object != NULL);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -070040 size_t offset = reinterpret_cast<size_t>(object->GetMonitor());
Brian Carlstromdb4d5402011-08-09 12:18:28 -070041 DCHECK_NE(0U, offset);
42 return offset;
43 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070044 static void ResetImageOffset(Object* object) {
45 DCHECK(object != NULL);
46 DCHECK(object->GetMonitor() != NULL); // should be an offset
47 object->SetMonitor(reinterpret_cast<Monitor*>(0));
48 }
49
50 bool InSourceSpace(const Object* object) {
51 DCHECK(source_space_ != NULL);
52 const byte* o = reinterpret_cast<const byte*>(object);
53 return (o >= source_space_->GetBase() && o < source_space_->GetLimit());
54 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070055 Object* GetImageAddress(const Object* object) {
56 if (object == NULL) {
57 return NULL;
58 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070059 // if object outside the relocating source_space_, assume unchanged
60 if (!InSourceSpace(object)) {
61 return const_cast<Object*>(object);
62 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070063 return reinterpret_cast<Object*>(image_base_ + GetImageOffset(object));
64 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070065 Object* GetLocalAddress(const Object* object) {
66 size_t offset = GetImageOffset(object);
67 byte* dst = image_->GetAddress() + offset;
68 return reinterpret_cast<Object*>(dst);
69 }
Brian Carlstromdb4d5402011-08-09 12:18:28 -070070
71 void CalculateNewObjectOffsets();
Brian Carlstrom4873d462011-08-21 15:23:39 -070072 static void CalculateNewObjectOffsetsCallback(Object* obj, void *arg);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070073
74 void CopyAndFixupObjects();
Brian Carlstrom4873d462011-08-21 15:23:39 -070075 static void CopyAndFixupObjectsCallback(Object* obj, void *arg);
76 void FixupClass(const Class* orig, Class* copy);
77 void FixupMethod(const Method* orig, Method* copy);
78 void FixupField(const Field* orig, Field* copy);
79 void FixupObject(const Object* orig, Object* copy);
80 void FixupObjectArray(const ObjectArray<Object>* orig, ObjectArray<Object>* copy);
81 void FixupInstanceFields(const Object* orig, Object* copy);
82 void FixupStaticFields(const Class* orig, Class* copy);
83 void FixupFields(const Object* orig, Object* copy, uint32_t ref_offsets, bool is_static);
Brian Carlstromdb4d5402011-08-09 12:18:28 -070084
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070085 void FixupDexCaches();
86 void FixupDexCache(const DexCache* orig, DexCache* copy);
87
88 // Space we are writing objects from
89 const Space* source_space_;
90
Brian Carlstromdb4d5402011-08-09 12:18:28 -070091 // memory mapped for generating the image
Elliott Hughes90a33692011-08-30 13:27:07 -070092 UniquePtr<MemMap> image_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070093
Brian Carlstrom4e777d42011-08-15 13:53:52 -070094 // Offset to the free space in image_
95 size_t image_top_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -070096
97 // Target base address for the output image
98 byte* image_base_;
Brian Carlstrom69b15fb2011-09-03 12:25:21 -070099
100 // DexCaches seen while scanning for fixing up CodeAndDirectMethods
101 typedef std::tr1::unordered_set<DexCache*, DexCacheHash> Set;
102 Set dex_caches_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700103};
104
105} // namespace art
106
Brian Carlstrom4a289ed2011-08-16 17:17:49 -0700107#endif // ART_SRC_IMAGE_WRITER_H_