ART: Swap-space in the compiler

Introduce a swap-space and corresponding allocator to transparently
switch native allocations to memory backed by a file.

Bug: 18596910

(cherry picked from commit 62746d8d9c4400e4764f162b22bfb1a32be287a9)

Change-Id: I131448f3907115054a592af73db86d2b9257ea33
diff --git a/compiler/compiled_method.cc b/compiler/compiled_method.cc
index 060af72..234e8b9 100644
--- a/compiler/compiled_method.cc
+++ b/compiler/compiled_method.cc
@@ -20,13 +20,13 @@
 namespace art {
 
 CompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
-                           const std::vector<uint8_t>& quick_code)
+                           const ArrayRef<const uint8_t>& quick_code)
     : compiler_driver_(compiler_driver), instruction_set_(instruction_set),
       quick_code_(nullptr) {
   SetCode(&quick_code);
 }
 
-void CompiledCode::SetCode(const std::vector<uint8_t>* quick_code) {
+void CompiledCode::SetCode(const ArrayRef<const uint8_t>* quick_code) {
   if (quick_code != nullptr) {
     CHECK(!quick_code->empty());
     quick_code_ = compiler_driver_->DeduplicateCode(*quick_code);
@@ -108,61 +108,88 @@
 
 CompiledMethod::CompiledMethod(CompilerDriver* driver,
                                InstructionSet instruction_set,
-                               const std::vector<uint8_t>& quick_code,
+                               const ArrayRef<const uint8_t>& quick_code,
                                const size_t frame_size_in_bytes,
                                const uint32_t core_spill_mask,
                                const uint32_t fp_spill_mask,
-                               SrcMap* src_mapping_table,
-                               const std::vector<uint8_t>& mapping_table,
-                               const std::vector<uint8_t>& vmap_table,
-                               const std::vector<uint8_t>& native_gc_map,
-                               const std::vector<uint8_t>* cfi_info,
+                               DefaultSrcMap* src_mapping_table,
+                               const ArrayRef<const uint8_t>& mapping_table,
+                               const ArrayRef<const uint8_t>& vmap_table,
+                               const ArrayRef<const uint8_t>& native_gc_map,
+                               const ArrayRef<const uint8_t>& cfi_info,
                                const ArrayRef<LinkerPatch>& patches)
     : CompiledCode(driver, instruction_set, quick_code), frame_size_in_bytes_(frame_size_in_bytes),
       core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask),
-      src_mapping_table_(driver->DeduplicateSrcMappingTable(src_mapping_table->Arrange())),
-      mapping_table_(driver->DeduplicateMappingTable(mapping_table)),
+      src_mapping_table_(src_mapping_table == nullptr ?
+          driver->DeduplicateSrcMappingTable(ArrayRef<SrcMapElem>()) :
+          driver->DeduplicateSrcMappingTable(ArrayRef<SrcMapElem>(src_mapping_table->Arrange()))),
+      mapping_table_(mapping_table.data() == nullptr ?
+          nullptr : driver->DeduplicateMappingTable(mapping_table)),
       vmap_table_(driver->DeduplicateVMapTable(vmap_table)),
-      gc_map_(driver->DeduplicateGCMap(native_gc_map)),
-      cfi_info_(driver->DeduplicateCFIInfo(cfi_info)),
-      patches_(patches.begin(), patches.end()) {
+      gc_map_(native_gc_map.data() == nullptr ? nullptr : driver->DeduplicateGCMap(native_gc_map)),
+      cfi_info_(cfi_info.data() == nullptr ? nullptr : driver->DeduplicateCFIInfo(cfi_info)),
+      patches_(patches.begin(), patches.end(), driver->GetSwapSpaceAllocator()) {
 }
 
-CompiledMethod::CompiledMethod(CompilerDriver* driver,
-                               InstructionSet instruction_set,
-                               const std::vector<uint8_t>& quick_code,
-                               const size_t frame_size_in_bytes,
-                               const uint32_t core_spill_mask,
-                               const uint32_t fp_spill_mask,
-                               const std::vector<uint8_t>& stack_map)
-    : CompiledCode(driver, instruction_set, quick_code),
-      frame_size_in_bytes_(frame_size_in_bytes),
-      core_spill_mask_(core_spill_mask),
-      fp_spill_mask_(fp_spill_mask),
-      src_mapping_table_(driver->DeduplicateSrcMappingTable(SrcMap())),
-      mapping_table_(nullptr),
-      vmap_table_(driver->DeduplicateVMapTable(stack_map)),
-      gc_map_(nullptr),
-      cfi_info_(nullptr),
-      patches_() {
+CompiledMethod* CompiledMethod::SwapAllocCompiledMethod(
+    CompilerDriver* driver,
+    InstructionSet instruction_set,
+    const ArrayRef<const uint8_t>& quick_code,
+    const size_t frame_size_in_bytes,
+    const uint32_t core_spill_mask,
+    const uint32_t fp_spill_mask,
+    DefaultSrcMap* src_mapping_table,
+    const ArrayRef<const uint8_t>& mapping_table,
+    const ArrayRef<const uint8_t>& vmap_table,
+    const ArrayRef<const uint8_t>& native_gc_map,
+    const ArrayRef<const uint8_t>& cfi_info,
+    const ArrayRef<LinkerPatch>& patches) {
+  SwapAllocator<CompiledMethod> alloc(driver->GetSwapSpaceAllocator());
+  CompiledMethod* ret = alloc.allocate(1);
+  alloc.construct(ret, driver, instruction_set, quick_code, frame_size_in_bytes, core_spill_mask,
+                  fp_spill_mask, src_mapping_table, mapping_table, vmap_table, native_gc_map,
+                  cfi_info, patches);
+  return ret;
 }
 
-CompiledMethod::CompiledMethod(CompilerDriver* driver,
-                               InstructionSet instruction_set,
-                               const std::vector<uint8_t>& code,
-                               const size_t frame_size_in_bytes,
-                               const uint32_t core_spill_mask,
-                               const uint32_t fp_spill_mask,
-                               const std::vector<uint8_t>* cfi_info)
-    : CompiledCode(driver, instruction_set, code),
-      frame_size_in_bytes_(frame_size_in_bytes),
-      core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask),
-      src_mapping_table_(driver->DeduplicateSrcMappingTable(SrcMap())),
-      mapping_table_(driver->DeduplicateMappingTable(std::vector<uint8_t>())),
-      vmap_table_(driver->DeduplicateVMapTable(std::vector<uint8_t>())),
-      gc_map_(driver->DeduplicateGCMap(std::vector<uint8_t>())),
-      cfi_info_(driver->DeduplicateCFIInfo(cfi_info)),
-      patches_() {
+CompiledMethod* CompiledMethod::SwapAllocCompiledMethodStackMap(
+    CompilerDriver* driver,
+    InstructionSet instruction_set,
+    const ArrayRef<const uint8_t>& quick_code,
+    const size_t frame_size_in_bytes,
+    const uint32_t core_spill_mask,
+    const uint32_t fp_spill_mask,
+    const ArrayRef<const uint8_t>& stack_map) {
+  SwapAllocator<CompiledMethod> alloc(driver->GetSwapSpaceAllocator());
+  CompiledMethod* ret = alloc.allocate(1);
+  alloc.construct(ret, driver, instruction_set, quick_code, frame_size_in_bytes, core_spill_mask,
+                  fp_spill_mask, nullptr, ArrayRef<const uint8_t>(), stack_map,
+                  ArrayRef<const uint8_t>(), ArrayRef<const uint8_t>(), ArrayRef<LinkerPatch>());
+  return ret;
+}
+
+CompiledMethod* CompiledMethod::SwapAllocCompiledMethodCFI(
+    CompilerDriver* driver,
+    InstructionSet instruction_set,
+    const ArrayRef<const uint8_t>& quick_code,
+    const size_t frame_size_in_bytes,
+    const uint32_t core_spill_mask,
+    const uint32_t fp_spill_mask,
+    const ArrayRef<const uint8_t>& cfi_info) {
+  SwapAllocator<CompiledMethod> alloc(driver->GetSwapSpaceAllocator());
+  CompiledMethod* ret = alloc.allocate(1);
+  alloc.construct(ret, driver, instruction_set, quick_code, frame_size_in_bytes, core_spill_mask,
+                  fp_spill_mask, nullptr, ArrayRef<const uint8_t>(),
+                  ArrayRef<const uint8_t>(), ArrayRef<const uint8_t>(),
+                  cfi_info, ArrayRef<LinkerPatch>());
+  return ret;
+}
+
+
+void CompiledMethod::ReleaseSwapAllocatedCompiledMethod(CompilerDriver* driver, CompiledMethod* m) {
+  SwapAllocator<CompiledMethod> alloc(driver->GetSwapSpaceAllocator());
+  alloc.destroy(m);
+  alloc.deallocate(m, 1);
 }
 
 }  // namespace art