Working dex2oat and oatexec

adb shell dex2oatd --dex-file=/system/framework/core.jar     --image=/system/framework/boot.oat --base=0x50000000 "'--method=Ljava/lang/System;logI(Ljava/lang/String;)V'" "'--method=Ljava/lang/System;log(CLjava/lang/String;Ljava/lang/Throwable;)V'"
adb shell dex2oatd --boot-dex-file=/system/framework/core.jar --boot=/system/framework/boot.oat --dex-file=/system/framework/art-test-dex-HelloWorld.jar --image=/system/framework/art-test-dex-HelloWorld.oat
adb shell oatexecd -Xbootclasspath:/system/framework/core.jar -Xbootimage:/system/framework/boot.oat -classpath /system/framework/art-test-dex-HelloWorld.jar -Ximage:/system/framework/art-test-dex-HelloWorld.oat HelloWorld

09-05 17:58:18.912  2385  2385 I System  : Hello, world!

Change-Id: I53e534068584f0c3a837313e4d517a0e4a7154fc
diff --git a/src/image_writer.h b/src/image_writer.h
index b63effe..3352adb 100644
--- a/src/image_writer.h
+++ b/src/image_writer.h
@@ -8,6 +8,7 @@
 #include <cstddef>
 
 #include "UniquePtr.h"
+#include "dex_cache.h"
 #include "mem_map.h"
 #include "object.h"
 #include "os.h"
@@ -19,33 +20,53 @@
 class ImageWriter {
 
  public:
-  ImageWriter() : image_top_(0), image_base_(NULL) {};
-  bool Write(Space* space, const char* filename, byte* image_base);
+  ImageWriter() : source_space_(NULL), image_top_(0), image_base_(NULL) {};
+  bool Write(const char* filename, uintptr_t image_base);
   ~ImageWriter() {};
 
  private:
 
-  bool Init(Space* space);
+  bool Init();
 
   // we use the lock word to store the offset of the object in the image
-  void SetImageOffset(Object* object, size_t offset) {
+  static void SetImageOffset(Object* object, size_t offset) {
     DCHECK(object != NULL);
     DCHECK(object->GetMonitor() == NULL);  // should be no lock
     DCHECK_NE(0U, offset);
     object->SetMonitor(reinterpret_cast<Monitor*>(offset));
   }
-  size_t GetImageOffset(const Object* object) {
+  static size_t GetImageOffset(const Object* object) {
     DCHECK(object != NULL);
     size_t offset = reinterpret_cast<size_t>(object->GetMonitor());
     DCHECK_NE(0U, offset);
     return offset;
   }
+  static void ResetImageOffset(Object* object) {
+    DCHECK(object != NULL);
+    DCHECK(object->GetMonitor() != NULL);  // should be an offset
+    object->SetMonitor(reinterpret_cast<Monitor*>(0));
+  }
+
+  bool InSourceSpace(const Object* object) {
+    DCHECK(source_space_ != NULL);
+    const byte* o = reinterpret_cast<const byte*>(object);
+    return (o >= source_space_->GetBase() && o < source_space_->GetLimit());
+  }
   Object* GetImageAddress(const Object* object) {
     if (object == NULL) {
       return NULL;
     }
+    // if object outside the relocating source_space_, assume unchanged
+    if (!InSourceSpace(object)) {
+      return const_cast<Object*>(object);
+    }
     return reinterpret_cast<Object*>(image_base_ + GetImageOffset(object));
   }
+  Object* GetLocalAddress(const Object* object) {
+    size_t offset = GetImageOffset(object);
+    byte* dst = image_->GetAddress() + offset;
+    return reinterpret_cast<Object*>(dst);
+  }
 
   void CalculateNewObjectOffsets();
   static void CalculateNewObjectOffsetsCallback(Object* obj, void *arg);
@@ -61,6 +82,12 @@
   void FixupStaticFields(const Class* orig, Class* copy);
   void FixupFields(const Object* orig, Object* copy, uint32_t ref_offsets, bool is_static);
 
+  void FixupDexCaches();
+  void FixupDexCache(const DexCache* orig, DexCache* copy);
+
+  // Space we are writing objects from
+  const Space* source_space_;
+
   // memory mapped for generating the image
   UniquePtr<MemMap> image_;
 
@@ -69,6 +96,10 @@
 
   // Target base address for the output image
   byte* image_base_;
+
+  // DexCaches seen while scanning for fixing up CodeAndDirectMethods
+  typedef std::tr1::unordered_set<DexCache*, DexCacheHash> Set;
+  Set dex_caches_;
 };
 
 }  // namespace art