Create separate Android.mk for main build targets

The runtime, compiler, dex2oat, and oatdump now are in seperate trees
to prevent dependency creep.  They can now be individually built
without rebuilding the rest of the art projects. dalvikvm and jdwpspy
were already this way. Builds in the art directory should behave as
before, building everything including tests.

Change-Id: Ic6b1151e5ed0f823c3dd301afd2b13eb2d8feb81
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h
new file mode 100644
index 0000000..1f97bf8
--- /dev/null
+++ b/compiler/oat_writer.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_OAT_WRITER_H_
+#define ART_SRC_OAT_WRITER_H_
+
+#include <stdint.h>
+
+#include <cstddef>
+
+#include "driver/compiler_driver.h"
+#include "mem_map.h"
+#include "oat.h"
+#include "mirror/class.h"
+#include "safe_map.h"
+#include "UniquePtr.h"
+
+namespace art {
+
+class OutputStream;
+
+// OatHeader         variable length with count of D OatDexFiles
+//
+// OatDexFile[0]     one variable sized OatDexFile with offsets to Dex and OatClasses
+// OatDexFile[1]
+// ...
+// OatDexFile[D]
+//
+// Dex[0]            one variable sized DexFile for each OatDexFile.
+// Dex[1]            these are literal copies of the input .dex files.
+// ...
+// Dex[D]
+//
+// OatClass[0]       one variable sized OatClass for each of C DexFile::ClassDefs
+// OatClass[1]       contains OatClass entries with class status, offsets to code, etc.
+// ...
+// OatClass[C]
+//
+// padding           if necessary so that the following code will be page aligned
+//
+// CompiledMethod    one variable sized blob with the contents of each CompiledMethod
+// CompiledMethod
+// CompiledMethod
+// CompiledMethod
+// CompiledMethod
+// CompiledMethod
+// ...
+// CompiledMethod
+//
+class OatWriter {
+ public:
+  // Write an oat file. Returns true on success, false on failure.
+  static bool Create(OutputStream& out,
+                     const std::vector<const DexFile*>& dex_files,
+                     uint32_t image_file_location_oat_checksum,
+                     uint32_t image_file_location_oat_begin,
+                     const std::string& image_file_location,
+                     const CompilerDriver& compiler)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ private:
+  OatWriter(const std::vector<const DexFile*>& dex_files,
+            uint32_t image_file_location_oat_checksum,
+            uint32_t image_file_location_oat_begin,
+            const std::string& image_file_location,
+            const CompilerDriver* compiler) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  ~OatWriter();
+
+  size_t InitOatHeader();
+  size_t InitOatDexFiles(size_t offset);
+  size_t InitDexFiles(size_t offset);
+  size_t InitOatClasses(size_t offset);
+  size_t InitOatCode(size_t offset)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  size_t InitOatCodeDexFiles(size_t offset)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  size_t InitOatCodeDexFile(size_t offset,
+                            size_t& oat_class_index,
+                            const DexFile& dex_file)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  size_t InitOatCodeClassDef(size_t offset,
+                             size_t oat_class_index, size_t class_def_index,
+                             const DexFile& dex_file,
+                             const DexFile::ClassDef& class_def)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  size_t InitOatCodeMethod(size_t offset, size_t oat_class_index, size_t class_def_index,
+                           size_t class_def_method_index, bool is_native, InvokeType type,
+                           uint32_t method_idx, const DexFile*)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  bool Write(OutputStream& out);
+  bool WriteTables(OutputStream& out);
+  size_t WriteCode(OutputStream& out);
+  size_t WriteCodeDexFiles(OutputStream& out, size_t offset);
+  size_t WriteCodeDexFile(OutputStream& out, size_t offset, size_t& oat_class_index,
+                          const DexFile& dex_file);
+  size_t WriteCodeClassDef(OutputStream& out, size_t offset, size_t oat_class_index,
+                           const DexFile& dex_file, const DexFile::ClassDef& class_def);
+  size_t WriteCodeMethod(OutputStream& out, size_t offset, size_t oat_class_index,
+                         size_t class_def_method_index, bool is_static, uint32_t method_idx,
+                         const DexFile& dex_file);
+
+  void ReportWriteFailure(const char* what, uint32_t method_idx, const DexFile& dex_file,
+                          OutputStream& out) const;
+
+  class OatDexFile {
+   public:
+    explicit OatDexFile(size_t offset, const DexFile& dex_file);
+    size_t SizeOf() const;
+    void UpdateChecksum(OatHeader& oat_header) const;
+    bool Write(OatWriter* oat_writer, OutputStream& out) const;
+
+    // Offset of start of OatDexFile from beginning of OatHeader. It is
+    // used to validate file position when writing.
+    size_t offset_;
+
+    // data to write
+    uint32_t dex_file_location_size_;
+    const uint8_t* dex_file_location_data_;
+    uint32_t dex_file_location_checksum_;
+    uint32_t dex_file_offset_;
+    std::vector<uint32_t> methods_offsets_;
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(OatDexFile);
+  };
+
+  class OatClass {
+   public:
+    explicit OatClass(size_t offset, mirror::Class::Status status, uint32_t methods_count);
+    size_t GetOatMethodOffsetsOffsetFromOatHeader(size_t class_def_method_index_) const;
+    size_t GetOatMethodOffsetsOffsetFromOatClass(size_t class_def_method_index_) const;
+    size_t SizeOf() const;
+    void UpdateChecksum(OatHeader& oat_header) const;
+    bool Write(OatWriter* oat_writer, OutputStream& out) const;
+
+    // Offset of start of OatClass from beginning of OatHeader. It is
+    // used to validate file position when writing. For Portable, it
+    // is also used to calculate the position of the OatMethodOffsets
+    // so that code pointers within the OatMethodOffsets can be
+    // patched to point to code in the Portable .o ELF objects.
+    size_t offset_;
+
+    // data to write
+    mirror::Class::Status status_;
+    std::vector<OatMethodOffsets> method_offsets_;
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(OatClass);
+  };
+
+  const CompilerDriver* const compiler_driver_;
+
+  // note OatFile does not take ownership of the DexFiles
+  const std::vector<const DexFile*>* dex_files_;
+
+  // dependencies on the image.
+  uint32_t image_file_location_oat_checksum_;
+  uint32_t image_file_location_oat_begin_;
+  std::string image_file_location_;
+
+  // data to write
+  OatHeader* oat_header_;
+  std::vector<OatDexFile*> oat_dex_files_;
+  std::vector<OatClass*> oat_classes_;
+  UniquePtr<const std::vector<uint8_t> > interpreter_to_interpreter_entry_;
+  UniquePtr<const std::vector<uint8_t> > interpreter_to_quick_entry_;
+  UniquePtr<const std::vector<uint8_t> > portable_resolution_trampoline_;
+  UniquePtr<const std::vector<uint8_t> > quick_resolution_trampoline_;
+
+  // output stats
+  uint32_t size_dex_file_alignment_;
+  uint32_t size_executable_offset_alignment_;
+  uint32_t size_oat_header_;
+  uint32_t size_oat_header_image_file_location_;
+  uint32_t size_dex_file_;
+  uint32_t size_interpreter_to_interpreter_entry_;
+  uint32_t size_interpreter_to_quick_entry_;
+  uint32_t size_portable_resolution_trampoline_;
+  uint32_t size_quick_resolution_trampoline_;
+  uint32_t size_stubs_alignment_;
+  uint32_t size_code_size_;
+  uint32_t size_code_;
+  uint32_t size_code_alignment_;
+  uint32_t size_mapping_table_;
+  uint32_t size_vmap_table_;
+  uint32_t size_gc_map_;
+  uint32_t size_oat_dex_file_location_size_;
+  uint32_t size_oat_dex_file_location_data_;
+  uint32_t size_oat_dex_file_location_checksum_;
+  uint32_t size_oat_dex_file_offset_;
+  uint32_t size_oat_dex_file_methods_offsets_;
+  uint32_t size_oat_class_status_;
+  uint32_t size_oat_class_method_offsets_;
+
+  template <class T> struct MapCompare {
+   public:
+    bool operator() (const T* const &a, const T* const &b) const {
+      return *a < *b;
+    }
+  };
+
+  // code mappings for deduplication
+  SafeMap<const std::vector<uint8_t>*, uint32_t, MapCompare<std::vector<uint8_t> > > code_offsets_;
+  SafeMap<const std::vector<uint16_t>*, uint32_t, MapCompare<std::vector<uint16_t> > > vmap_table_offsets_;
+  SafeMap<const std::vector<uint32_t>*, uint32_t, MapCompare<std::vector<uint32_t> > > mapping_table_offsets_;
+  SafeMap<const std::vector<uint8_t>*, uint32_t, MapCompare<std::vector<uint8_t> > > gc_map_offsets_;
+
+  DISALLOW_COPY_AND_ASSIGN(OatWriter);
+};
+
+}  // namespace art
+
+#endif  // ART_SRC_OAT_WRITER_H_