Remove opening of DexFile from pointer

Change-Id: I158e75e9e72f1dcc579742ff08c80d3f857852b3
diff --git a/build/Android.common.mk b/build/Android.common.mk
index 481fbc0..69580cc 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -211,6 +211,7 @@
 	AbstractMethod \
 	AllFields \
 	CreateMethodDescriptor \
+	ExceptionHandle \
 	ExceptionTest \
 	Fibonacci \
 	HelloWorld \
diff --git a/src/common_test.h b/src/common_test.h
index 8491dbb..a7c5ea8 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -13,8 +13,10 @@
 #include "compiler.h"
 #include "constants.h"
 #include "dex_file.h"
+#include "file.h"
 #include "gtest/gtest.h"
 #include "heap.h"
+#include "os.h"
 #include "runtime.h"
 #include "stl_util.h"
 #include "stringprintf.h"
@@ -26,11 +28,22 @@
 
 static inline const DexFile* OpenDexFileBase64(const char* base64,
                                                const std::string& location) {
+  // decode base64
   CHECK(base64 != NULL);
   size_t length;
   byte* dex_bytes = DecodeBase64(base64, &length);
   CHECK(dex_bytes != NULL);
-  const DexFile* dex_file = DexFile::OpenPtr(dex_bytes, length, location);
+
+  // write to provided file
+  UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
+  CHECK(file.get() != NULL);
+  if (!file->WriteFully(dex_bytes, length)) {
+    PLOG(FATAL) << "Failed to write base64 as dex file";
+  }
+  file.reset();
+
+  // read dex file
+  const DexFile* dex_file = DexFile::OpenFile(location, location, "");
   CHECK(dex_file != NULL);
   return dex_file;
 }
diff --git a/src/dex_file.cc b/src/dex_file.cc
index d437a3f..b4cf837 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -71,29 +71,11 @@
 }
 
 void DexFile::ChangePermissions(int prot) const {
-  closer_->ChangePermissions(prot);
-}
-
-DexFile::Closer::~Closer() {}
-
-DexFile::MmapCloser::MmapCloser(void* addr, size_t length) : addr_(addr), length_(length) {
-  CHECK(addr != NULL);
-}
-DexFile::MmapCloser::~MmapCloser() {
-  if (munmap(addr_, length_) == -1) {
-    PLOG(INFO) << "munmap failed";
-  }
-}
-void DexFile::MmapCloser::ChangePermissions(int prot) {
-  if (mprotect(addr_, length_, prot) != 0) {
+  if (mprotect(mem_map_->GetAddress(), mem_map_->GetLength(), prot) != 0) {
     PLOG(FATAL) << "Failed to change dex file permissions to " << prot;
   }
 }
 
-DexFile::PtrCloser::PtrCloser(byte* addr) : addr_(addr) {}
-DexFile::PtrCloser::~PtrCloser() { delete[] addr_; }
-void DexFile::PtrCloser::ChangePermissions(int prot) {}
-
 const DexFile* DexFile::OpenFile(const std::string& filename,
                                  const std::string& original_location,
                                  const std::string& strip_location_prefix) {
@@ -116,16 +98,15 @@
     return NULL;
   }
   size_t length = sbuf.st_size;
-  void* addr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
-  if (addr == MAP_FAILED) {
-    PLOG(ERROR) << "mmap \"" << filename << "\" failed";
+  UniquePtr<MemMap> map(MemMap::Map(length, PROT_READ, MAP_PRIVATE, fd, 0));
+  if (map.get() == NULL) {
+    LOG(ERROR) << "mmap \"" << filename << "\" failed";
     close(fd);
     return NULL;
   }
   close(fd);
-  byte* dex_file = reinterpret_cast<byte*>(addr);
-  Closer* closer = new MmapCloser(addr, length);
-  return Open(dex_file, length, location.ToString(), closer);
+  byte* dex_file = map->GetAddress();
+  return Open(dex_file, length, location.ToString(), map.release());
 }
 
 static const char* kClassesDex = "classes.dex";
@@ -368,15 +349,9 @@
   // NOTREACHED
 }
 
-const DexFile* DexFile::OpenPtr(byte* ptr, size_t length, const std::string& location) {
-  CHECK(ptr != NULL);
-  DexFile::Closer* closer = new PtrCloser(ptr);
-  return Open(ptr, length, location, closer);
-}
-
 const DexFile* DexFile::Open(const byte* dex_bytes, size_t length,
-                             const std::string& location, Closer* closer) {
-  UniquePtr<DexFile> dex_file(new DexFile(dex_bytes, length, location, closer));
+                             const std::string& location, MemMap* mem_map) {
+  UniquePtr<DexFile> dex_file(new DexFile(dex_bytes, length, location, mem_map));
   if (!dex_file->Init()) {
     return NULL;
   } else {
diff --git a/src/dex_file.h b/src/dex_file.h
index e313d74..cb979ae 100644
--- a/src/dex_file.h
+++ b/src/dex_file.h
@@ -12,6 +12,7 @@
 #include "jni.h"
 #include "leb128.h"
 #include "logging.h"
+#include "mem_map.h"
 #include "mutex.h"
 #include "stringpiece.h"
 #include "strutil.h"
@@ -336,13 +337,6 @@
   static const DexFile* OpenZip(const std::string& filename,
                                 const std::string& strip_location_prefix);
 
-  // Opens a .dex file from a new allocated pointer.  location is used
-  // to identify the source, for example "/system/framework/core.jar"
-  // or "contrived-test-42". When initializing a ClassLinker from an
-  // image, the location is used to match DexCaches the image to their
-  // corresponding DexFiles.N
-  static const DexFile* OpenPtr(byte* ptr, size_t length, const std::string& location);
-
   // Closes a .dex file.
   virtual ~DexFile();
 
@@ -844,45 +838,17 @@
   void ChangePermissions(int prot) const;
 
  private:
-  // Helper class to deallocate underlying storage.
-  class Closer {
-   public:
-    virtual ~Closer();
-    virtual void ChangePermissions(int prot) = 0;
-  };
-
-  // Helper class to deallocate mmap-backed .dex files.
-  class MmapCloser : public Closer {
-   public:
-    MmapCloser(void* addr, size_t length);
-    virtual ~MmapCloser();
-    virtual void ChangePermissions(int prot);
-   private:
-    void* addr_;
-    size_t length_;
-  };
-
-  // Helper class for deallocating new/delete-backed .dex files.
-  class PtrCloser : public Closer {
-   public:
-    PtrCloser(byte* addr);
-    virtual ~PtrCloser();
-    virtual void ChangePermissions(int prot);
-   private:
-    byte* addr_;
-  };
-
   // Opens a .dex file at the given address.
   static const DexFile* Open(const byte* dex_file,
                              size_t length,
                              const std::string& location,
-                             Closer* closer);
+                             MemMap* mem_map);
 
-  DexFile(const byte* addr, size_t length, const std::string& location, Closer* closer)
+  DexFile(const byte* addr, size_t length, const std::string& location, MemMap* mem_map)
       : base_(addr),
         length_(length),
         location_(location),
-        closer_(closer),
+        mem_map_(mem_map),
         dex_object_lock_("a dex_object_lock_"),
         dex_object_(NULL),
         header_(0),
@@ -894,7 +860,7 @@
         class_defs_(0) {
     CHECK(addr != NULL);
     CHECK_GT(length, 0U);
-    CHECK(closer != NULL);
+    CHECK(mem_map != NULL);
   }
 
   // Top-level initializer that calls other Init methods.
@@ -928,8 +894,8 @@
   // path to DexCache::GetLocation when loading from an image.
   const std::string location_;
 
-  // Helper object to free the underlying allocation.
-  UniquePtr<Closer> closer_;
+  // Manages the underlying memory allocation.
+  UniquePtr<MemMap> mem_map_;
 
   // A cached com.android.dex.Dex instance, possibly NULL. Use GetDexObject.
   mutable Mutex dex_object_lock_;
diff --git a/src/dex_file_test.cc b/src/dex_file_test.cc
index 3a9b6f4..ad3b17b 100644
--- a/src/dex_file_test.cc
+++ b/src/dex_file_test.cc
@@ -41,7 +41,8 @@
   "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
 
 TEST_F(DexFileTest, Header) {
-  UniquePtr<const DexFile> raw(OpenDexFileBase64(kRawDex, "kRawDex"));
+  ScratchFile tmp;
+  UniquePtr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename()));
   ASSERT_TRUE(raw.get() != NULL);
 
   const DexFile::Header& header = raw->GetHeader();
diff --git a/src/exception_test.cc b/src/exception_test.cc
index 2e9cf3f..7acc584 100644
--- a/src/exception_test.cc
+++ b/src/exception_test.cc
@@ -14,76 +14,31 @@
 
 namespace art {
 
-// package java.lang;
-// import java.io.IOException;
-// class Object {};
-// public class MyClass {
-//   int f() throws Exception {
-//     try {
-//         g(1);
-//     } catch (IOException e) {
-//         return 1;
-//     } catch (Exception e) {
-//         return 2;
-//     }
-//     try {
-//         g(2);
-//     } catch (IOException e) {
-//         return 3;
-//     }
-//     return 0;
-//   }
-//   void g(int doThrow) throws Exception {
-//     if (doThrow == 1)
-//         throw new Exception();
-//     else if (doThrow == 2)
-//         throw new IOException();
-//   }
-// }
-
-static const char kMyClassExceptionHandleDex[] =
-  "ZGV4CjAzNQC/bXXtLZJLN1GzLr+ncrvPSl70n8t0yAjgAwAAcAAAAHhWNBIAAAAAAAAAACgDAAAN"
-  "AAAAcAAAAAcAAACkAAAAAwAAAMAAAAAAAAAAAAAAAAYAAADkAAAAAgAAABQBAACMAgAAVAEAAD4C"
-  "AABGAgAASQIAAGUCAAB8AgAAkwIAAKgCAAC8AgAAygIAAM0CAADRAgAA1AIAANcCAAABAAAAAgAA"
-  "AAMAAAAEAAAABQAAAAYAAAAIAAAAAQAAAAAAAAAAAAAACAAAAAYAAAAAAAAACQAAAAYAAAA4AgAA"
-  "AgABAAAAAAADAAEAAAAAAAQAAQAAAAAABAAAAAoAAAAEAAIACwAAAAUAAQAAAAAABQAAAAAAAAD/"
-  "////AAAAAAcAAAAAAAAACQMAAAAAAAAEAAAAAQAAAAUAAAAAAAAABwAAABgCAAATAwAAAAAAAAEA"
-  "AAABAwAAAQABAAAAAADeAgAAAQAAAA4AAAABAAEAAQAAAOMCAAAEAAAAcBAFAAAADgAEAAEAAgAC"
-  "AOgCAAAVAAAAEiISERIQbiAEAAMAEiBuIAQAAwASAA8ADQABECj9DQABICj6DQASMCj3AAADAAAA"
-  "AwABAAcAAAADAAYAAgICDAMPAQISAAAAAwACAAEAAAD3AgAAEwAAABIQMwIIACIAAwBwEAEAAAAn"
-  "ABIgMwIIACIAAgBwEAAAAAAnAA4AAAAAAAAAAAAAAAIAAAAAAAAAAwAAAFQBAAAEAAAAVAEAAAEA"
-  "AAAAAAY8aW5pdD4AAUkAGkxkYWx2aWsvYW5ub3RhdGlvbi9UaHJvd3M7ABVMamF2YS9pby9JT0V4"
-  "Y2VwdGlvbjsAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwATTGphdmEvbGFuZy9NeUNsYXNzOwASTGph"
-  "dmEvbGFuZy9PYmplY3Q7AAxNeUNsYXNzLmphdmEAAVYAAlZJAAFmAAFnAAV2YWx1ZQADAAcOAAQA"
-  "Bw4ABwAHLFFOAnYsLR4tIR4AFQEABw48aTxpAAIBAQwcARgDAAABAAWAgATcAgAAAQICgYAE8AID"
-  "AIgDAQDgAwAAAA8AAAAAAAAAAQAAAAAAAAABAAAADQAAAHAAAAACAAAABwAAAKQAAAADAAAAAwAA"
-  "AMAAAAAFAAAABgAAAOQAAAAGAAAAAgAAABQBAAADEAAAAQAAAFQBAAABIAAABAAAAFwBAAAGIAAA"
-  "AQAAABgCAAABEAAAAQAAADgCAAACIAAADQAAAD4CAAADIAAABAAAAN4CAAAEIAAAAQAAAAEDAAAA"
-  "IAAAAgAAAAkDAAAAEAAAAQAAACgDAAA=";
-
 class ExceptionTest : public CommonTest {
  protected:
   virtual void SetUp() {
     CommonTest::SetUp();
 
-    dex_.reset(OpenDexFileBase64(kMyClassExceptionHandleDex, "kMyClassExceptionHandleDex"));
-    ASSERT_TRUE(dex_.get() != NULL);
-    const ClassLoader* class_loader = AllocPathClassLoader(dex_.get());
-    ASSERT_TRUE(class_loader != NULL);
-    my_klass_ = class_linker_->FindClass("Ljava/lang/MyClass;", class_loader);
+    const ClassLoader* class_loader = LoadDex("ExceptionHandle");
+    my_klass_ = class_linker_->FindClass("LExceptionHandle;", class_loader);
     ASSERT_TRUE(my_klass_ != NULL);
+
+    dex_ = &Runtime::Current()->GetClassLinker()->FindDexFile(my_klass_->GetDexCache());
+
     ByteArray* fake_code = ByteArray::Alloc(12);
     ASSERT_TRUE(fake_code != NULL);
     IntArray* fake_mapping_data = IntArray::Alloc(2);
     ASSERT_TRUE(fake_mapping_data != NULL);
     fake_mapping_data->Set(0, 3);  // offset 3
     fake_mapping_data->Set(1, 3);  // maps to dex offset 3
+
     method_f_ = my_klass_->FindVirtualMethod("f", "()I");
     ASSERT_TRUE(method_f_ != NULL);
     method_f_->SetFrameSizeInBytes(kStackAlignment);
     method_f_->SetReturnPcOffsetInBytes(kStackAlignment-kPointerSize);
     method_f_->SetCodeArray(fake_code, kThumb2);
     method_f_->SetMappingTable(fake_mapping_data);
+
     method_g_ = my_klass_->FindVirtualMethod("g", "(I)V");
     ASSERT_TRUE(method_g_ != NULL);
     method_g_->SetFrameSizeInBytes(kStackAlignment);
@@ -92,7 +47,7 @@
     method_g_->SetMappingTable(fake_mapping_data);
   }
 
-  UniquePtr<const DexFile> dex_;
+  const DexFile* dex_;
 
   Method* method_f_;
   Method* method_g_;
@@ -102,7 +57,7 @@
 };
 
 TEST_F(ExceptionTest, FindCatchHandler) {
-  const DexFile::CodeItem *code_item = dex_->GetCodeItem(method_f_->GetCodeItemOffset());
+  const DexFile::CodeItem* code_item = dex_->GetCodeItem(method_f_->GetCodeItemOffset());
 
   ASSERT_TRUE(code_item != NULL);
 
@@ -169,16 +124,16 @@
       Decode<ObjectArray<StackTraceElement>*>(env, ste_array);
 
   ASSERT_TRUE(trace_array->Get(0) != NULL);
-  EXPECT_STREQ("java.lang.MyClass",
+  EXPECT_STREQ("ExceptionHandle",
                trace_array->Get(0)->GetDeclaringClass()->ToModifiedUtf8().c_str());
-  EXPECT_STREQ("MyClass.java", trace_array->Get(0)->GetFileName()->ToModifiedUtf8().c_str());
+  EXPECT_STREQ("ExceptionHandle.java", trace_array->Get(0)->GetFileName()->ToModifiedUtf8().c_str());
   EXPECT_STREQ("g", trace_array->Get(0)->GetMethodName()->ToModifiedUtf8().c_str());
   EXPECT_EQ(22, trace_array->Get(0)->GetLineNumber());
 
   ASSERT_TRUE(trace_array->Get(1) != NULL);
-  EXPECT_STREQ("java.lang.MyClass",
+  EXPECT_STREQ("ExceptionHandle",
                trace_array->Get(1)->GetDeclaringClass()->ToModifiedUtf8().c_str());
-  EXPECT_STREQ("MyClass.java", trace_array->Get(1)->GetFileName()->ToModifiedUtf8().c_str());
+  EXPECT_STREQ("ExceptionHandle.java", trace_array->Get(1)->GetFileName()->ToModifiedUtf8().c_str());
   EXPECT_STREQ("f", trace_array->Get(1)->GetMethodName()->ToModifiedUtf8().c_str());
   EXPECT_EQ(7, trace_array->Get(1)->GetLineNumber());
 }
diff --git a/src/stack_walk.cc b/src/stack_walk.cc
index bc7b3a3..2c29e75 100644
--- a/src/stack_walk.cc
+++ b/src/stack_walk.cc
@@ -6,7 +6,6 @@
 #include "class_linker.h"
 #include "common_test.h"
 #include "dex_verifier.h"
-// #include "heap.h"
 #include "object.h"
 #include "jni.h"
 
diff --git a/test/ExceptionHandle/ExceptionHandle.java b/test/ExceptionHandle/ExceptionHandle.java
new file mode 100644
index 0000000..94c6f5b
--- /dev/null
+++ b/test/ExceptionHandle/ExceptionHandle.java
@@ -0,0 +1,27 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+import java.io.IOException;
+
+public class ExceptionHandle {
+    int f() throws Exception {
+        try {
+            g(1);
+        } catch (IOException e) {
+            return 1;
+        } catch (Exception e) {
+            return 2;
+        }
+        try {
+            g(2);
+        } catch (IOException e) {
+            return 3;
+        }
+        return 0;
+    }
+    void g(int doThrow) throws Exception {
+        if (doThrow == 1) {
+            throw new Exception();
+        } else if (doThrow == 2) {
+            throw new IOException();
+        }
+    }
+}