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.h b/compiler/compiled_method.h
index d93db03..6013507 100644
--- a/compiler/compiled_method.h
+++ b/compiler/compiled_method.h
@@ -25,6 +25,7 @@
#include "method_reference.h"
#include "utils.h"
#include "utils/array_ref.h"
+#include "utils/swap_space.h"
namespace llvm {
class Function;
@@ -38,17 +39,17 @@
public:
// For Quick to supply an code blob
CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
- const std::vector<uint8_t>& quick_code);
+ const ArrayRef<const uint8_t>& quick_code);
InstructionSet GetInstructionSet() const {
return instruction_set_;
}
- const std::vector<uint8_t>* GetQuickCode() const {
+ const SwapVector<uint8_t>* GetQuickCode() const {
return quick_code_;
}
- void SetCode(const std::vector<uint8_t>* quick_code);
+ void SetCode(const ArrayRef<const uint8_t>* quick_code);
bool operator==(const CompiledCode& rhs) const;
@@ -78,7 +79,7 @@
const InstructionSet instruction_set_;
// Used to store the PIC code for Quick.
- std::vector<uint8_t>* quick_code_;
+ SwapVector<uint8_t>* quick_code_;
// There are offsets from the oatdata symbol to where the offset to
// the compiled method will be found. These are computed by the
@@ -109,8 +110,23 @@
}
};
-class SrcMap FINAL : public std::vector<SrcMapElem> {
+template <class Allocator>
+class SrcMap FINAL : public std::vector<SrcMapElem, Allocator> {
public:
+ using std::vector<SrcMapElem, Allocator>::begin;
+ using typename std::vector<SrcMapElem, Allocator>::const_iterator;
+ using std::vector<SrcMapElem, Allocator>::empty;
+ using std::vector<SrcMapElem, Allocator>::end;
+ using std::vector<SrcMapElem, Allocator>::resize;
+ using std::vector<SrcMapElem, Allocator>::shrink_to_fit;
+ using std::vector<SrcMapElem, Allocator>::size;
+
+ explicit SrcMap() {}
+
+ template <class InputIt>
+ SrcMap(InputIt first, InputIt last, const Allocator& alloc)
+ : std::vector<SrcMapElem, Allocator>(first, last, alloc) {}
+
void SortByFrom() {
std::sort(begin(), end(), [] (const SrcMapElem& lhs, const SrcMapElem& rhs) -> bool {
return lhs.from_ < rhs.from_;
@@ -158,6 +174,10 @@
}
};
+using DefaultSrcMap = SrcMap<std::allocator<SrcMapElem>>;
+using SwapSrcMap = SrcMap<SwapAllocator<SrcMapElem>>;
+
+
enum LinkerPatchType {
kLinkerPatchMethod,
kLinkerPatchCall,
@@ -255,40 +275,57 @@
class CompiledMethod FINAL : public CompiledCode {
public:
- // Constructs a CompiledMethod for Quick.
+ // Constructs a CompiledMethod.
+ // Note: Consider using the static allocation methods below that will allocate the CompiledMethod
+ // in the swap space.
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 = ArrayRef<LinkerPatch>());
- // Constructs a CompiledMethod for Optimizing.
- 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>& vmap_table);
-
- // Constructs a CompiledMethod for the QuickJniCompiler.
- 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>* cfi_info);
-
~CompiledMethod() {}
+ static 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 = ArrayRef<LinkerPatch>());
+
+ static 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);
+
+ static 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);
+
+ static void ReleaseSwapAllocatedCompiledMethod(CompilerDriver* driver, CompiledMethod* m);
+
size_t GetFrameSizeInBytes() const {
return frame_size_in_bytes_;
}
@@ -301,29 +338,29 @@
return fp_spill_mask_;
}
- const SrcMap& GetSrcMappingTable() const {
+ const SwapSrcMap& GetSrcMappingTable() const {
DCHECK(src_mapping_table_ != nullptr);
return *src_mapping_table_;
}
- std::vector<uint8_t> const* GetMappingTable() const {
+ SwapVector<uint8_t> const* GetMappingTable() const {
return mapping_table_;
}
- const std::vector<uint8_t>& GetVmapTable() const {
+ const SwapVector<uint8_t>& GetVmapTable() const {
DCHECK(vmap_table_ != nullptr);
return *vmap_table_;
}
- std::vector<uint8_t> const* GetGcMap() const {
+ SwapVector<uint8_t> const* GetGcMap() const {
return gc_map_;
}
- const std::vector<uint8_t>* GetCFIInfo() const {
+ const SwapVector<uint8_t>* GetCFIInfo() const {
return cfi_info_;
}
- const std::vector<LinkerPatch>& GetPatches() const {
+ const SwapVector<LinkerPatch>& GetPatches() const {
return patches_;
}
@@ -335,19 +372,19 @@
// For quick code, a bit mask describing spilled FPR callee-save registers.
const uint32_t fp_spill_mask_;
// For quick code, a set of pairs (PC, Line) mapping from native PC offset to Java line
- SrcMap* src_mapping_table_;
+ SwapSrcMap* src_mapping_table_;
// For quick code, a uleb128 encoded map from native PC offset to dex PC aswell as dex PC to
// native PC offset. Size prefixed.
- std::vector<uint8_t>* mapping_table_;
+ SwapVector<uint8_t>* mapping_table_;
// For quick code, a uleb128 encoded map from GPR/FPR register to dex register. Size prefixed.
- std::vector<uint8_t>* vmap_table_;
+ SwapVector<uint8_t>* vmap_table_;
// For quick code, a map keyed by native PC indices to bitmaps describing what dalvik registers
// are live.
- std::vector<uint8_t>* gc_map_;
+ SwapVector<uint8_t>* gc_map_;
// For quick code, a FDE entry for the debug_frame section.
- std::vector<uint8_t>* cfi_info_;
+ SwapVector<uint8_t>* cfi_info_;
// For quick code, linker patches needed by the method.
- std::vector<LinkerPatch> patches_;
+ SwapVector<LinkerPatch> patches_;
};
} // namespace art