Compile method one-by-one.
Change-Id: Ic56fb397f3bd6dee32372eb875261a3383eaf30c
diff --git a/src/common_test.h b/src/common_test.h
index cdcac24..58d0219 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -177,14 +177,10 @@
MakeExecutable(code_array->GetData(), code_array->GetLength());
}
-#if !defined(ART_USE_LLVM_COMPILER) // LLVM compilation uses ELF instead
static void MakeExecutable(const std::vector<uint8_t>& code) {
CHECK_NE(code.size(), 0U);
MakeExecutable(&code[0], code.size());
}
-#else
- static void MakeExecutable(const std::vector<uint8_t>&) {}
-#endif
// Create an OatMethod based on pointers (for unit tests)
OatFile::OatMethod CreateOatMethod(const void* code,
@@ -205,13 +201,7 @@
reinterpret_cast<uint32_t>(gc_map),
reinterpret_cast<uint32_t>(invoke_stub)
#if defined(ART_USE_LLVM_COMPILER)
- , NULL,
- static_cast<uint16_t>(-1u),
- static_cast<uint16_t>(-1u),
- static_cast<uint16_t>(-1u),
- static_cast<uint16_t>(-1u),
- static_cast<uint16_t>(-1u),
- static_cast<uint16_t>(-1u)
+ , 0
#endif
);
}
@@ -224,17 +214,12 @@
compiler_->FindInvokeStub(mh.IsStatic(), mh.GetShorty());
CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method);
- const Method::InvokeStub* method_invoke_stub = NULL;
- if (compiled_invoke_stub->IsExecutableInElf()) {
- method_invoke_stub =
- compiler_->GetMethodInvokeStubAddr(compiled_invoke_stub, method);
- } else {
- const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
- MakeExecutable(invoke_stub);
- method_invoke_stub = reinterpret_cast<const Method::InvokeStub*>(
+ const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
+ MakeExecutable(invoke_stub);
+ const Method::InvokeStub* method_invoke_stub =
+ reinterpret_cast<const Method::InvokeStub*>(
CompiledCode::CodePointer(&invoke_stub[0],
compiled_invoke_stub->GetInstructionSet()));
- }
LOG(INFO) << "MakeExecutable " << PrettyMethod(method)
<< " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
@@ -247,14 +232,10 @@
method->GetDexMethodIndex()));
CHECK(compiled_method != NULL) << PrettyMethod(method);
- const void* method_code = NULL;
- if (compiled_method->IsExecutableInElf()) {
- method_code = compiler_->GetMethodCodeAddr(compiled_method, method);
- } else {
- const std::vector<uint8_t>& code = compiled_method->GetCode();
- MakeExecutable(code);
- method_code = CompiledMethod::CodePointer(&code[0], compiled_method->GetInstructionSet());
- }
+ const std::vector<uint8_t>& code = compiled_method->GetCode();
+ MakeExecutable(code);
+ const void* method_code = CompiledMethod::CodePointer(&code[0],
+ compiled_method->GetInstructionSet());
LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
@@ -380,9 +361,6 @@
image_classes_.reset(new std::set<std::string>);
compiler_.reset(new Compiler(instruction_set, true, 2, false, image_classes_.get(),
true, true));
-#if defined(ART_USE_LLVM_COMPILER)
- compiler_->EnableAutoElfLoading();
-#endif
Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
}
diff --git a/src/compiled_method.h b/src/compiled_method.h
index 7ddde0c..ca3a597 100644
--- a/src/compiled_method.h
+++ b/src/compiled_method.h
@@ -32,22 +32,14 @@
class CompiledCode {
public:
CompiledCode(InstructionSet instruction_set)
- : instruction_set_(instruction_set), elf_idx_(-1), elf_func_idx_(-1) {
+ : instruction_set_(instruction_set) {
}
CompiledCode(InstructionSet instruction_set, const std::vector<uint8_t>& code)
- : instruction_set_(instruction_set), code_(code), elf_idx_(-1),
- elf_func_idx_(-1) {
+ : instruction_set_(instruction_set), code_(code) {
CHECK_NE(code.size(), 0U);
}
- CompiledCode(InstructionSet instruction_set,
- uint16_t elf_idx,
- uint16_t elf_func_idx)
- : instruction_set_(instruction_set), elf_idx_(elf_idx),
- elf_func_idx_(elf_func_idx) {
- }
-
InstructionSet GetInstructionSet() const {
return instruction_set_;
}
@@ -57,6 +49,7 @@
}
void SetCode(const std::vector<uint8_t>& code) {
+ CHECK_NE(code.size(), 0U);
code_ = code;
}
@@ -64,18 +57,6 @@
return (code_ == rhs.code_);
}
- bool IsExecutableInElf() const {
- return (elf_idx_ != static_cast<uint16_t>(-1u));
- }
-
- uint16_t GetElfIndex() const {
- return elf_idx_;
- }
-
- uint16_t GetElfFuncIndex() const {
- return elf_func_idx_;
- }
-
// To align an offset from a page-aligned value to make it suitable
// for code storage. For example on ARM, to ensure that PC relative
// valu computations work out as expected.
@@ -95,10 +76,6 @@
private:
const InstructionSet instruction_set_;
std::vector<uint8_t> code_;
-
- // LLVM-specific fields
- uint16_t elf_idx_;
- uint16_t elf_func_idx_;
};
class CompiledMethod : public CompiledCode {
@@ -124,9 +101,8 @@
// Constructs a CompiledMethod for the LLVM compiler.
CompiledMethod(InstructionSet instruction_set,
- uint16_t elf_idx,
- uint16_t elf_func_idx)
- : CompiledCode(instruction_set, elf_idx, elf_func_idx),
+ const std::vector<uint8_t>& code)
+ : CompiledCode(instruction_set, code),
frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0),
fp_spill_mask_(0) {
}
@@ -162,12 +138,6 @@
explicit CompiledInvokeStub(InstructionSet instruction_set,
const std::vector<uint8_t>& code);
- explicit CompiledInvokeStub(InstructionSet instruction_set,
- uint16_t elf_idx,
- uint16_t elf_func_idx)
- : CompiledCode(instruction_set, elf_idx, elf_func_idx) {
- }
-
~CompiledInvokeStub();
};
diff --git a/src/compiler.cc b/src/compiler.cc
index a726606..272ba9e 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -319,14 +319,8 @@
compiler_(NULL),
compiler_context_(NULL),
jni_compiler_(NULL),
-#if !defined(ART_USE_LLVM_COMPILER)
- create_invoke_stub_(NULL) {
-#else
- create_invoke_stub_(NULL),
- compiler_enable_auto_elf_loading_(NULL),
- compiler_get_method_code_addr_(NULL),
- compiler_get_method_invoke_stub_addr_(NULL) {
-#endif
+ create_invoke_stub_(NULL)
+{
std::string compiler_so_name(MakeCompilerSoName(instruction_set_));
compiler_library_ = dlopen(compiler_so_name.c_str(), RTLD_LAZY);
if (compiler_library_ == NULL) {
@@ -353,12 +347,6 @@
#if defined(ART_USE_LLVM_COMPILER)
create_proxy_stub_ = FindFunction<CreateProxyStubFn>(
compiler_so_name, compiler_library_, "ArtCreateProxyStub");
- compiler_enable_auto_elf_loading_ = FindFunction<CompilerEnableAutoElfLoadingFn>(
- compiler_so_name, compiler_library_, "compilerLLVMEnableAutoElfLoading");
- compiler_get_method_code_addr_ = FindFunction<CompilerGetMethodCodeAddrFn>(
- compiler_so_name, compiler_library_, "compilerLLVMGetMethodCodeAddr");
- compiler_get_method_invoke_stub_addr_ = FindFunction<CompilerGetMethodInvokeStubAddrFn>(
- compiler_so_name, compiler_library_, "compilerLLVMGetMethodInvokeStubAddr");
#endif
CHECK(!Runtime::Current()->IsStarted());
@@ -395,10 +383,17 @@
STLDeleteElements(&methods_to_patch_);
}
#if defined(ART_USE_LLVM_COMPILER)
- CompilerCallbackFn f = FindFunction<CompilerCallbackFn>(MakeCompilerSoName(instruction_set_),
- compiler_library_,
- "compilerLLVMDispose");
- (*f)(*this);
+ // Uninitialize compiler_context_
+ typedef void (*UninitCompilerContextFn)(Compiler&);
+
+ std::string compiler_so_name(MakeCompilerSoName(instruction_set_));
+
+ UninitCompilerContextFn uninit_compiler_context =
+ FindFunction<void (*)(Compiler&)>(compiler_so_name,
+ compiler_library_,
+ "ArtUnInitCompilerContext");
+
+ uninit_compiler_context(*this);
#endif
if (compiler_library_ != NULL) {
VLOG(compiler) << "dlclose(" << compiler_library_ << ")";
@@ -511,12 +506,6 @@
void Compiler::PostCompile(ClassLoader* class_loader,
const std::vector<const DexFile*>& dex_files) {
SetGcMaps(class_loader, dex_files);
-#if defined(ART_USE_LLVM_COMPILER)
- CompilerCallbackFn f = FindFunction<CompilerCallbackFn>(MakeCompilerSoName(instruction_set_),
- compiler_library_,
- "compilerLLVMMaterializeRemainder");
- (*f)(*this);
-#endif
}
bool Compiler::IsImageClass(const std::string& descriptor) const {
@@ -1683,31 +1672,4 @@
}
#endif
-#if defined(ART_USE_LLVM_COMPILER)
-void Compiler::EnableAutoElfLoading() {
- compiler_enable_auto_elf_loading_(*this);
-}
-
-const void* Compiler::GetMethodCodeAddr(const CompiledMethod* cm,
- const Method* method) const {
- return compiler_get_method_code_addr_(*this, cm, method);
-}
-
-const Method::InvokeStub* Compiler::GetMethodInvokeStubAddr(const CompiledInvokeStub* cm,
- const Method* method) const {
- return compiler_get_method_invoke_stub_addr_(*this, cm, method);
-}
-
-std::vector<ElfImage> Compiler::GetElfImages() const {
- typedef std::vector<ElfImage> (*GetElfImagesFn)(const Compiler&);
-
- GetElfImagesFn get_elf_images =
- FindFunction<GetElfImagesFn>(MakeCompilerSoName(instruction_set_),
- compiler_library_,
- "compilerLLVMGetElfImages");
-
- return get_elf_images(*this);
-}
-#endif
-
} // namespace art
diff --git a/src/compiler.h b/src/compiler.h
index 5202967..46d3647 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -25,7 +25,6 @@
#include "compiled_method.h"
#include "dex_cache.h"
#include "dex_file.h"
-#include "elf_image.h"
#include "instruction_set.h"
#include "invoke_type.h"
#include "oat_file.h"
@@ -146,34 +145,6 @@
void SetBitcodeFileName(std::string const& filename);
#endif
-#if defined(ART_USE_LLVM_COMPILER)
- void EnableAutoElfLoading();
-
- const void* GetMethodCodeAddr(const CompiledMethod* cm,
- const Method* method) const;
-
- const Method::InvokeStub* GetMethodInvokeStubAddr(const CompiledInvokeStub* cm,
- const Method* method) const;
-
- std::vector<ElfImage> GetElfImages() const;
-#else
- void EnableAutoElfLoader() { }
-
- const void* GetMethodCodeAddr(const CompiledMethod*,
- const Method*) const {
- return NULL;
- }
-
- const Method::InvokeStub* GetMethodInvokeStubAddr(const CompiledInvokeStub*,
- const Method*) const {
- return NULL;
- }
-
- std::vector<ElfImage> GetElfImages() const {
- return std::vector<ElfImage>();
- }
-#endif
-
void SetCompilerContext(void* compiler_context) {
compiler_context_ = compiler_context;
}
diff --git a/src/compiler_llvm/compilation_unit.cc b/src/compiler_llvm/compilation_unit.cc
index 38faf61..fdbf575 100644
--- a/src/compiler_llvm/compilation_unit.cc
+++ b/src/compiler_llvm/compilation_unit.cc
@@ -17,6 +17,7 @@
#include "compilation_unit.h"
#include "compiled_method.h"
+#include "compiler_llvm.h"
#include "file.h"
#include "instruction_set.h"
#include "ir_builder.h"
@@ -47,8 +48,10 @@
#include <llvm/DerivedTypes.h>
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
+#include <llvm/Object/ObjectFile.h>
#include <llvm/PassManager.h>
#include <llvm/Support/Debug.h>
+#include <llvm/Support/ELF.h>
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/MemoryBuffer.h>
@@ -77,37 +80,6 @@
namespace {
-class UpdateFrameSizePass : public llvm::MachineFunctionPass {
- public:
- static char ID;
-
- UpdateFrameSizePass() : llvm::MachineFunctionPass(ID), cunit_(NULL) {
- LOG(FATAL) << "Unexpected instantiation of UpdateFrameSizePass";
- // NOTE: We have to declare this constructor for llvm::RegisterPass, but
- // this constructor won't work because we have no information on
- // CompilationUnit. Thus, we should place a LOG(FATAL) here.
- }
-
- UpdateFrameSizePass(art::compiler_llvm::CompilationUnit* cunit)
- : llvm::MachineFunctionPass(ID), cunit_(cunit) {
- }
-
- virtual bool runOnMachineFunction(llvm::MachineFunction &MF) {
- cunit_->UpdateFrameSizeInBytes(MF.getFunction(),
- MF.getFrameInfo()->getStackSize());
- return false;
- }
-
- private:
- art::compiler_llvm::CompilationUnit* cunit_;
-};
-
-char UpdateFrameSizePass::ID = 0;
-
-llvm::RegisterPass<UpdateFrameSizePass> reg_update_frame_size_pass_(
- "update-frame-size", "Update frame size pass", false, false);
-
-
// TODO: We may need something to manage these passes.
// TODO: We need high-level IR to analysis and do this at the IRBuilder level.
class AddSuspendCheckToLoopLatchPass : public llvm::LoopPass {
@@ -167,10 +139,10 @@
llvm::Module* makeLLVMModuleContents(llvm::Module* module);
-CompilationUnit::CompilationUnit(InstructionSet insn_set, size_t elf_idx)
-: cunit_lock_("compilation_unit_lock"), insn_set_(insn_set), elf_idx_(elf_idx),
- context_(new llvm::LLVMContext()), compiled_methods_map_(new CompiledMethodMap()),
- mem_usage_(0), num_elf_funcs_(0) {
+CompilationUnit::CompilationUnit(const CompilerLLVM* compiler_llvm,
+ size_t cunit_idx)
+: compiler_llvm_(compiler_llvm), cunit_idx_(cunit_idx),
+ context_(new llvm::LLVMContext()) {
// Create the module and include the runtime function declaration
module_ = new llvm::Module("art", *context_);
@@ -180,7 +152,7 @@
irb_.reset(new IRBuilder(*context_, *module_));
// We always need a switch case, so just use a normal function.
- switch(insn_set_) {
+ switch(GetInstructionSet()) {
default:
runtime_support_.reset(new RuntimeSupportBuilder(*context_, *module_, *irb_));
break;
@@ -205,57 +177,56 @@
}
-bool CompilationUnit::Materialize(size_t thread_count) {
- MutexLock GUARD(cunit_lock_);
-
- // Materialize the bitcode to elf_image_
- llvm::raw_string_ostream str_os(elf_image_);
- bool success = MaterializeToFile(str_os);
- LOG(INFO) << "Compilation Unit: " << elf_idx_ << (success ? " (done)" : " (failed)");
-
- // Free the resources
- context_.reset(NULL);
- irb_.reset(NULL);
- module_ = NULL;
- runtime_support_.reset(NULL);
- compiled_methods_map_.reset(NULL);
-
- return success;
+InstructionSet CompilationUnit::GetInstructionSet() const {
+ return compiler_llvm_->GetInstructionSet();
}
-void CompilationUnit::RegisterCompiledMethod(const llvm::Function* func,
- CompiledMethod* compiled_method) {
- MutexLock GUARD(cunit_lock_);
- compiled_methods_map_->Put(func, compiled_method);
-}
+bool CompilationUnit::Materialize() {
+ std::string elf_image;
-
-void CompilationUnit::UpdateFrameSizeInBytes(const llvm::Function* func,
- size_t frame_size_in_bytes) {
- MutexLock GUARD(cunit_lock_);
- SafeMap<const llvm::Function*, CompiledMethod*>::iterator iter =
- compiled_methods_map_->find(func);
-
- if (iter != compiled_methods_map_->end()) {
- CompiledMethod* compiled_method = iter->second;
- compiled_method->SetFrameSizeInBytes(frame_size_in_bytes);
-
- if (frame_size_in_bytes > 1728u) {
- LOG(WARNING) << "Huge frame size: " << frame_size_in_bytes
- << " elf_idx=" << compiled_method->GetElfIndex()
- << " elf_func_idx=" << compiled_method->GetElfFuncIndex();
- }
+ // Compile and prelink llvm::Module
+ if (!MaterializeToString(elf_image)) {
+ LOG(ERROR) << "Failed to materialize compilation unit " << cunit_idx_;
+ DeleteResources();
+ return false;
}
+
+#if 0
+ // Dump the ELF image for debugging
+ std::string filename(StringPrintf("%s/Art%zu.elf",
+ GetArtCacheOrDie(GetAndroidData()).c_str(),
+ cunit_idx_));
+ UniquePtr<File> output(OS::OpenFile(filename.c_str(), true));
+ output->WriteFully(elf_image.data(), elf_image.size());
+#endif
+
+ // Extract the .text section and prelink the code
+ if (!ExtractCodeAndPrelink(elf_image)) {
+ LOG(ERROR) << "Failed to extract code from compilation unit " << cunit_idx_;
+ DeleteResources();
+ return false;
+ }
+
+ DeleteResources();
+ return true;
}
-bool CompilationUnit::MaterializeToFile(llvm::raw_ostream& out_stream) {
+
+bool CompilationUnit::MaterializeToString(std::string& str_buffer) {
+ llvm::raw_string_ostream str_os(str_buffer);
+ return MaterializeToRawOStream(str_os);
+}
+
+
+bool CompilationUnit::MaterializeToRawOStream(llvm::raw_ostream& out_stream) {
// Lookup the LLVM target
char const* target_triple = NULL;
char const* target_cpu = "";
char const* target_attr = NULL;
- switch (insn_set_) {
+ InstructionSet insn_set = GetInstructionSet();
+ switch (insn_set) {
case kThumb2:
target_triple = "thumb-none-linux-gnueabi";
target_cpu = "cortex-a9";
@@ -281,7 +252,7 @@
break;
default:
- LOG(FATAL) << "Unknown instruction set: " << insn_set_;
+ LOG(FATAL) << "Unknown instruction set: " << insn_set;
}
std::string errmsg;
@@ -375,11 +346,6 @@
return false;
}
- // FIXME: Unable to run the UpdateFrameSizePass pass since it tries to
- // update the value reside in the different address space.
- // Add pass to update the frame_size_in_bytes_
- //pm.add(new ::UpdateFrameSizePass(this));
-
// Run the per-function optimization
fpm.doInitialization();
for (llvm::Module::iterator F = module_->begin(), E = module_->end();
@@ -395,5 +361,130 @@
return true;
}
+
+bool CompilationUnit::ExtractCodeAndPrelink(const std::string& elf_image) {
+ llvm::OwningPtr<llvm::MemoryBuffer> elf_image_buff(
+ llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(elf_image.data(),
+ elf_image.size())));
+
+ llvm::OwningPtr<llvm::object::ObjectFile> elf_file(
+ llvm::object::ObjectFile::createELFObjectFile(elf_image_buff.take()));
+
+ llvm::error_code ec;
+
+ const ProcedureLinkageTable& plt = compiler_llvm_->GetProcedureLinkageTable();
+
+ for (llvm::object::section_iterator
+ sec_iter = elf_file->begin_sections(),
+ sec_end = elf_file->end_sections();
+ sec_iter != sec_end; sec_iter.increment(ec)) {
+
+ CHECK(ec == 0) << "Failed to read section because " << ec.message();
+
+ // Read the section information
+ llvm::StringRef name;
+ uint64_t alignment = 0u;
+ uint64_t size = 0u;
+
+ CHECK(sec_iter->getName(name) == 0);
+ CHECK(sec_iter->getSize(size) == 0);
+ CHECK(sec_iter->getAlignment(alignment) == 0);
+
+ if (name == ".data" || name == ".bss" || name == ".rodata") {
+ if (size > 0) {
+ LOG(FATAL) << "Compilation unit " << cunit_idx_ << " has non-empty "
+ << name.str() << " section";
+ }
+
+ } else if (name == "" || name == ".rel.text" ||
+ name == ".ARM.attributes" || name == ".symtab" ||
+ name == ".strtab" || name == ".shstrtab") {
+ // We can ignore these sections. We don't have to copy them into
+ // the result Oat file.
+
+ } else if (name == ".text") {
+ // Ensure the alignment requirement is less than or equal to
+ // kArchAlignment
+ CheckCodeAlign(alignment);
+
+ // Copy the compiled code
+ llvm::StringRef contents;
+ CHECK(sec_iter->getContents(contents) == 0);
+
+ copy(contents.data(),
+ contents.data() + contents.size(),
+ back_inserter(compiled_code_));
+
+ // Prelink the compiled code
+ for (llvm::object::relocation_iterator
+ rel_iter = sec_iter->begin_relocations(),
+ rel_end = sec_iter->end_relocations(); rel_iter != rel_end;
+ rel_iter.increment(ec)) {
+
+ CHECK(ec == 0) << "Failed to read relocation because " << ec.message();
+
+ // Read the relocation information
+ llvm::object::SymbolRef sym_ref;
+ uint64_t rel_offset = 0;
+ uint64_t rel_type = 0;
+ int64_t rel_addend = 0;
+
+ CHECK(rel_iter->getSymbol(sym_ref) == 0);
+ CHECK(rel_iter->getOffset(rel_offset) == 0);
+ CHECK(rel_iter->getType(rel_type) == 0);
+ CHECK(rel_iter->getAdditionalInfo(rel_addend) == 0);
+
+ // Read the symbol related to this relocation fixup
+ llvm::StringRef sym_name;
+ CHECK(sym_ref.getName(sym_name) == 0);
+
+ // Relocate the fixup.
+ // TODO: Support more relocation type.
+ CHECK(rel_type == llvm::ELF::R_ARM_ABS32);
+ CHECK_LE(rel_offset + 4, compiled_code_.size());
+
+ uintptr_t dest_addr = plt.GetEntryAddress(sym_name.str().c_str());
+ uintptr_t final_addr = dest_addr + rel_addend;
+ compiled_code_[rel_offset] = final_addr & 0xff;
+ compiled_code_[rel_offset + 1] = (final_addr >> 8) & 0xff;
+ compiled_code_[rel_offset + 2] = (final_addr >> 16) & 0xff;
+ compiled_code_[rel_offset + 3] = (final_addr >> 24) & 0xff;
+ }
+
+ } else {
+ LOG(WARNING) << "Unexpected section: " << name.str();
+ }
+ }
+
+ return true;
+}
+
+
+// Check whether the align is less than or equal to the code alignment of
+// that architecture. Since the Oat writer only guarantee that the compiled
+// method being aligned to kArchAlignment, we have no way to align the ELf
+// section if the section alignment is greater than kArchAlignment.
+void CompilationUnit::CheckCodeAlign(uint32_t align) const {
+ InstructionSet insn_set = GetInstructionSet();
+ switch (insn_set) {
+ case kThumb2:
+ case kArm:
+ CHECK_LE(align, static_cast<uint32_t>(kArmAlignment));
+ break;
+
+ case kX86:
+ CHECK_LE(align, static_cast<uint32_t>(kX86Alignment));
+ break;
+
+ case kMips:
+ CHECK_LE(align, static_cast<uint32_t>(kMipsAlignment));
+ break;
+
+ default:
+ LOG(FATAL) << "Unknown instruction set: " << insn_set;
+ }
+}
+
+
} // namespace compiler_llvm
} // namespace art
diff --git a/src/compiler_llvm/compilation_unit.h b/src/compiler_llvm/compilation_unit.h
index d391620..576b65f 100644
--- a/src/compiler_llvm/compilation_unit.h
+++ b/src/compiler_llvm/compilation_unit.h
@@ -18,7 +18,6 @@
#define ART_SRC_COMPILER_LLVM_COMPILATION_UNIT_H_
#include "../mutex.h"
-#include "elf_image.h"
#include "globals.h"
#include "instruction_set.h"
#include "logging.h"
@@ -44,81 +43,52 @@
namespace art {
namespace compiler_llvm {
+class CompilerLLVM;
class IRBuilder;
class CompilationUnit {
public:
- CompilationUnit(InstructionSet insn_set, size_t elf_idx);
+ CompilationUnit(const CompilerLLVM* compiler_llvm,
+ size_t cunit_idx);
~CompilationUnit();
- size_t GetElfIndex() const {
- return elf_idx_;
+ size_t GetIndex() const {
+ return cunit_idx_;
}
- InstructionSet GetInstructionSet() const {
- cunit_lock_.AssertHeld();
- return insn_set_;
- }
+ InstructionSet GetInstructionSet() const;
llvm::LLVMContext* GetLLVMContext() const {
- cunit_lock_.AssertHeld();
return context_.get();
}
llvm::Module* GetModule() const {
- cunit_lock_.AssertHeld();
return module_;
}
IRBuilder* GetIRBuilder() const {
- cunit_lock_.AssertHeld();
return irb_.get();
}
- ElfImage GetElfImage() const {
- MutexLock GUARD(cunit_lock_);
- CHECK_GT(elf_image_.size(), 0u);
- return ElfImage(elf_image_);
- }
-
- uint16_t AcquireUniqueElfFuncIndex() {
- cunit_lock_.AssertHeld();
- CHECK(num_elf_funcs_ < UINT16_MAX);
- return num_elf_funcs_++;
- }
-
void SetBitcodeFileName(const std::string& bitcode_filename) {
- MutexLock GUARD(cunit_lock_);
bitcode_filename_ = bitcode_filename;
}
- bool Materialize(size_t thread_count);
+ bool Materialize();
bool IsMaterialized() const {
- MutexLock GUARD(cunit_lock_);
return (context_.get() == NULL);
}
- bool IsMaterializeThresholdReached() const {
- MutexLock GUARD(cunit_lock_);
- return (mem_usage_ > 1000000u); // (threshold: 1 MB)
+ const std::vector<uint8_t>& GetCompiledCode() const {
+ DCHECK(IsMaterialized());
+ return compiled_code_;
}
- void AddMemUsageApproximation(size_t usage) {
- MutexLock GUARD(cunit_lock_);
- mem_usage_ += usage;
- }
-
- void RegisterCompiledMethod(const llvm::Function* func, CompiledMethod* cm);
-
- void UpdateFrameSizeInBytes(const llvm::Function* func, size_t frame_size_in_bytes);
-
- mutable Mutex cunit_lock_;
-
private:
- InstructionSet insn_set_;
- const size_t elf_idx_;
+ const CompilerLLVM* compiler_llvm_;
+ const size_t cunit_idx_;
UniquePtr<llvm::LLVMContext> context_;
UniquePtr<IRBuilder> irb_;
@@ -126,15 +96,24 @@
llvm::Module* module_;
std::string bitcode_filename_;
- std::string elf_image_;
- typedef SafeMap<const llvm::Function*, CompiledMethod*> CompiledMethodMap;
- UniquePtr<CompiledMethodMap> compiled_methods_map_;
+ std::vector<uint8_t> compiled_code_;
- size_t mem_usage_;
- uint16_t num_elf_funcs_;
+ SafeMap<const llvm::Function*, CompiledMethod*> compiled_methods_map_;
- bool MaterializeToFile(llvm::raw_ostream& out_stream);
+ void CheckCodeAlign(uint32_t offset) const;
+
+ void DeleteResources() {
+ module_ = NULL; // Managed by context_
+ context_.reset(NULL);
+ irb_.reset(NULL);
+ runtime_support_.reset(NULL);
+ }
+
+ bool MaterializeToString(std::string& str_buffer);
+ bool MaterializeToRawOStream(llvm::raw_ostream& out_stream);
+
+ bool ExtractCodeAndPrelink(const std::string& elf_image);
};
} // namespace compiler_llvm
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index 6c8188e..b793fbd 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -22,8 +22,6 @@
#include "compiled_method.h"
#include "compiler.h"
#include "dex_cache.h"
-#include "elf_image.h"
-#include "elf_loader.h"
#include "ir_builder.h"
#include "jni_compiler.h"
#include "method_compiler.h"
@@ -95,9 +93,9 @@
CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set)
- : compiler_(compiler), compiler_lock_("llvm_compiler_lock"),
- insn_set_(insn_set), curr_cunit_(NULL) {
-
+ : compiler_(compiler), insn_set_(insn_set),
+ num_cunits_lock_("compilation unit counter lock"), num_cunits_(0),
+ plt_(insn_set) {
// Initialize LLVM libraries
pthread_once(&llvm_initialized, InitializeLLVM);
@@ -105,152 +103,21 @@
CompilerLLVM::~CompilerLLVM() {
- STLDeleteElements(&cunits_);
}
-void CompilerLLVM::EnsureCompilationUnit() {
- compiler_lock_.AssertHeld();
-
- if (curr_cunit_ != NULL) {
- return;
- }
-
- // Allocate compilation unit
- size_t cunit_idx = cunits_.size();
- curr_cunit_ = new CompilationUnit(insn_set_, cunit_idx);
-
- // Register compilation unit
- cunits_.push_back(curr_cunit_);
-}
-
-
-void CompilerLLVM::MaterializeRemainder() {
- compiler_lock_.Lock();
- // Localize
- CompilationUnit* cunit = curr_cunit_;
- // Reset the curr_cuit_
- curr_cunit_ = NULL;
- compiler_lock_.Unlock();
-
- if (cunit != NULL) {
- Materialize(cunit);
- }
-}
-
-
-void CompilerLLVM::MaterializeIfThresholdReached() {
- compiler_lock_.Lock();
- // Localize
- CompilationUnit* cunit = curr_cunit_;
-
- if (curr_cunit_ != NULL && curr_cunit_->IsMaterializeThresholdReached()) {
- // Delete the compilation unit
- curr_cunit_ = NULL;
- } else {
- // Reset cunit such that Materialize() won't be invoked
- cunit = NULL;
- }
-
- compiler_lock_.Unlock();
-
- if (cunit != NULL) {
- Materialize(cunit);
- }
-}
-
-
-void CompilerLLVM::Materialize(CompilationUnit* cunit) {
- DCHECK(cunit != NULL);
- DCHECK(!cunit->IsMaterialized());
-
- // Write bitcode to file when filename is set
- if (IsBitcodeFileNameAvailable()) {
- const size_t cunit_idx = cunits_.size();
- cunit->SetBitcodeFileName(
- StringPrintf("%s-%zu", bitcode_filename_.c_str(), cunit_idx));
- }
-
- // Materialize the llvm::Module into ELF object file
- cunit->Materialize(compiler_->GetThreadCount());
-
- // Load ELF image when automatic ELF loading is enabled
- if (IsAutoElfLoadingEnabled()) {
- LoadElfFromCompilationUnit(cunit);
- }
-}
-
-
-void CompilerLLVM::EnableAutoElfLoading() {
- MutexLock GUARD(compiler_lock_);
-
- if (IsAutoElfLoadingEnabled()) {
- // If there is an existing ELF loader, then do nothing.
- // Because the existing ELF loader may have returned some code address
- // already. If we replace the existing ELF loader with
- // elf_loader_.reset(...), then it is possible to have some dangling
- // pointer.
- return;
- }
-
- // Create ELF loader and load the materialized CompilationUnit
- elf_loader_.reset(new ElfLoader());
-
- for (size_t i = 0; i < cunits_.size(); ++i) {
- if (cunits_[i]->IsMaterialized()) {
- LoadElfFromCompilationUnit(cunits_[i]);
- }
- }
-}
-
-
-void CompilerLLVM::LoadElfFromCompilationUnit(const CompilationUnit* cunit) {
- MutexLock GUARD(compiler_lock_);
- DCHECK(cunit->IsMaterialized()) << cunit->GetElfIndex();
-
- if (!elf_loader_->LoadElfAt(cunit->GetElfIndex(),
- cunit->GetElfImage(),
- OatFile::kRelocAll)) {
- LOG(ERROR) << "Failed to load ELF from compilation unit "
- << cunit->GetElfIndex();
- }
-}
-
-
-const void* CompilerLLVM::GetMethodCodeAddr(const CompiledMethod* cm) const {
- return elf_loader_->GetMethodCodeAddr(cm->GetElfIndex(),
- cm->GetElfFuncIndex());
-}
-
-
-const Method::InvokeStub* CompilerLLVM::
-GetMethodInvokeStubAddr(const CompiledInvokeStub* cm) const {
- return elf_loader_->GetMethodInvokeStubAddr(cm->GetElfIndex(),
- cm->GetElfFuncIndex());
-}
-
-
-std::vector<ElfImage> CompilerLLVM::GetElfImages() const {
- std::vector<ElfImage> result;
-
- for (size_t i = 0; i < cunits_.size(); ++i) {
- result.push_back(cunits_[i]->GetElfImage());
- }
-
- return result;
+CompilationUnit* CompilerLLVM::AllocateCompilationUnit() {
+ MutexLock GUARD(num_cunits_lock_);
+ return new CompilationUnit(this, num_cunits_++);
}
CompiledMethod* CompilerLLVM::
CompileDexMethod(OatCompilationUnit* oat_compilation_unit) {
- MutexLock GUARD(compiler_lock_);
-
- EnsureCompilationUnit();
-
- MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
+ UniquePtr<CompilationUnit> cunit(AllocateCompilationUnit());
UniquePtr<MethodCompiler> method_compiler(
- new MethodCompiler(curr_cunit_, compiler_, oat_compilation_unit));
+ new MethodCompiler(cunit.get(), compiler_, oat_compilation_unit));
return method_compiler->Compile();
}
@@ -258,14 +125,10 @@
CompiledMethod* CompilerLLVM::
CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) {
- MutexLock GUARD(compiler_lock_);
-
- EnsureCompilationUnit();
-
- MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
+ UniquePtr<CompilationUnit> cunit(AllocateCompilationUnit());
UniquePtr<JniCompiler> jni_compiler(
- new JniCompiler(curr_cunit_, *compiler_, oat_compilation_unit));
+ new JniCompiler(cunit.get(), *compiler_, oat_compilation_unit));
return jni_compiler->Compile();
}
@@ -273,28 +136,20 @@
CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static,
char const *shorty) {
- MutexLock GUARD(compiler_lock_);
-
- EnsureCompilationUnit();
-
- MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
+ UniquePtr<CompilationUnit> cunit(AllocateCompilationUnit());
UniquePtr<StubCompiler> stub_compiler(
- new StubCompiler(curr_cunit_, *compiler_));
+ new StubCompiler(cunit.get(), *compiler_));
return stub_compiler->CreateInvokeStub(is_static, shorty);
}
CompiledInvokeStub* CompilerLLVM::CreateProxyStub(char const *shorty) {
- MutexLock GUARD(compiler_lock_);
-
- EnsureCompilationUnit();
-
- MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
+ UniquePtr<CompilationUnit> cunit(AllocateCompilationUnit());
UniquePtr<StubCompiler> stub_compiler(
- new StubCompiler(curr_cunit_, *compiler_));
+ new StubCompiler(cunit.get(), *compiler_));
return stub_compiler->CreateProxyStub(shorty);
}
@@ -324,6 +179,11 @@
compiler.SetCompilerContext(compiler_llvm);
}
+extern "C" void ArtUnInitCompilerContext(art::Compiler& compiler) {
+ delete ContextOf(compiler);
+ compiler.SetCompilerContext(NULL);
+}
+
extern "C" art::CompiledMethod* ArtCompileMethod(art::Compiler& compiler,
const art::DexFile::CodeItem* code_item,
uint32_t access_flags, uint32_t method_idx,
@@ -338,7 +198,6 @@
method_idx, access_flags);
art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
art::CompiledMethod* result = compiler_llvm->CompileDexMethod(&oat_compilation_unit);
- compiler_llvm->MaterializeIfThresholdReached();
return result;
}
@@ -354,7 +213,6 @@
art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
art::CompiledMethod* result = compiler_llvm->CompileNativeMethod(&oat_compilation_unit);
- compiler_llvm->MaterializeIfThresholdReached();
return result;
}
@@ -364,7 +222,6 @@
uint32_t shorty_len) {
art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
art::CompiledInvokeStub* result = compiler_llvm->CreateInvokeStub(is_static, shorty);
- compiler_llvm->MaterializeIfThresholdReached();
return result;
}
@@ -373,7 +230,6 @@
uint32_t shorty_len) {
art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
art::CompiledInvokeStub* result = compiler_llvm->CreateProxyStub(shorty);
- compiler_llvm->MaterializeIfThresholdReached();
return result;
}
@@ -381,37 +237,3 @@
std::string const& filename) {
ContextOf(compiler)->SetBitcodeFileName(filename);
}
-
-extern "C" void compilerLLVMMaterializeRemainder(art::Compiler& compiler) {
- ContextOf(compiler)->MaterializeRemainder();
-}
-
-extern "C" void compilerLLVMEnableAutoElfLoading(art::Compiler& compiler) {
- art::compiler_llvm::CompilerLLVM* compiler_llvm =
- reinterpret_cast<art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
- return compiler_llvm->EnableAutoElfLoading();
-}
-
-extern "C" const void* compilerLLVMGetMethodCodeAddr(const art::Compiler& compiler,
- const art::CompiledMethod* cm,
- const art::Method*) {
- const art::compiler_llvm::CompilerLLVM* compiler_llvm =
- reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
- return compiler_llvm->GetMethodCodeAddr(cm);
-}
-
-extern "C" const art::Method::InvokeStub* compilerLLVMGetMethodInvokeStubAddr(const art::Compiler& compiler,
- const art::CompiledInvokeStub* cm,
- const art::Method*) {
- const art::compiler_llvm::CompilerLLVM* compiler_llvm =
- reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
- return compiler_llvm->GetMethodInvokeStubAddr(cm);
-}
-
-extern "C" std::vector<art::ElfImage> compilerLLVMGetElfImages(const art::Compiler& compiler) {
- return ContextOf(compiler)->GetElfImages();
-}
-
-extern "C" void compilerLLVMDispose(art::Compiler& compiler) {
- delete ContextOf(compiler);
-}
diff --git a/src/compiler_llvm/compiler_llvm.h b/src/compiler_llvm/compiler_llvm.h
index 7cc4a0e..24a766e 100644
--- a/src/compiler_llvm/compiler_llvm.h
+++ b/src/compiler_llvm/compiler_llvm.h
@@ -19,10 +19,10 @@
#include "compiler.h"
#include "dex_file.h"
-#include "elf_image.h"
#include "instruction_set.h"
#include "macros.h"
#include "object.h"
+#include "procedure_linkage_table.h"
#include <UniquePtr.h>
@@ -54,7 +54,6 @@
namespace compiler_llvm {
class CompilationUnit;
-class ElfLoader;
class IRBuilder;
class CompilerLLVM {
@@ -63,10 +62,6 @@
~CompilerLLVM();
- void MaterializeIfThresholdReached();
-
- void MaterializeRemainder();
-
Compiler* GetCompiler() const {
return compiler_;
}
@@ -75,31 +70,10 @@
return insn_set_;
}
- size_t GetNumCompilationUnits() const {
- return cunits_.size();
- }
-
- const CompilationUnit* GetCompilationUnit(size_t i) const {
- return cunits_[i];
- }
-
void SetBitcodeFileName(std::string const& filename) {
bitcode_filename_ = filename;
}
- void EnableAutoElfLoading();
-
- bool IsAutoElfLoadingEnabled() const {
- return (elf_loader_.get() != NULL);
- }
-
- const void* GetMethodCodeAddr(const CompiledMethod* cm) const;
-
- const Method::InvokeStub* GetMethodInvokeStubAddr(
- const CompiledInvokeStub* cm) const;
-
- std::vector<ElfImage> GetElfImages() const;
-
CompiledMethod* CompileDexMethod(OatCompilationUnit* oat_compilation_unit);
CompiledMethod* CompileNativeMethod(OatCompilationUnit* oat_compilation_unit);
@@ -108,32 +82,29 @@
CompiledInvokeStub* CreateProxyStub(const char *shorty);
+ const ProcedureLinkageTable& GetProcedureLinkageTable() const {
+ return plt_;
+ }
+
private:
- void EnsureCompilationUnit();
+ CompilationUnit* AllocateCompilationUnit();
void Materialize(CompilationUnit* cunit);
- void LoadElfFromCompilationUnit(const CompilationUnit* cunit);
-
bool IsBitcodeFileNameAvailable() const {
return !bitcode_filename_.empty();
}
Compiler* compiler_;
- public:
- Mutex compiler_lock_;
-
- private:
InstructionSet insn_set_;
- CompilationUnit* curr_cunit_;
-
- std::vector<CompilationUnit*> cunits_;
+ Mutex num_cunits_lock_;
+ size_t num_cunits_;
std::string bitcode_filename_;
- UniquePtr<ElfLoader> elf_loader_;
+ ProcedureLinkageTable plt_;
DISALLOW_COPY_AND_ASSIGN(CompilerLLVM);
};
diff --git a/src/compiler_llvm/elf_loader.cc b/src/compiler_llvm/elf_loader.cc
deleted file mode 100644
index 8432a07..0000000
--- a/src/compiler_llvm/elf_loader.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include "elf_loader.h"
-
-#include "compiled_method.h"
-#include "elf_image.h"
-#include "logging.h"
-#include "oat_file.h"
-#include "object.h"
-#include "runtime_support_llvm.h"
-#include "utils_llvm.h"
-
-#include <android/librsloader.h>
-
-namespace art {
-namespace compiler_llvm {
-
-
-ElfLoader::~ElfLoader() {
- // Release every ELF object
- for (size_t i = 0; i < executables_.size(); ++i) {
- rsloaderDisposeExec(executables_[i]);
- }
-}
-
-
-bool ElfLoader::LoadElfAt(size_t elf_idx,
- const ElfImage& elf_image,
- OatFile::RelocationBehavior reloc) {
- if (elf_idx < executables_.size() && executables_[elf_idx] != NULL) {
- return false;
- }
-
- if (elf_idx >= executables_.size()) {
- executables_.resize(elf_idx + 1);
- elf_images_.resize(elf_idx + 1);
- }
-
- RSExecRef executable = rsloaderLoadExecutable(elf_image.begin(),
- elf_image.size(),
- reloc == OatFile::kRelocNone ? 1 : 0);
-
- if (executable == NULL) {
- LOG(WARNING) << "Failed to load ELF"
- << " image: " << static_cast<const void*>(elf_image.begin())
- << " size: " << elf_image.size();
- return false;
- }
-
- if (reloc == OatFile::kRelocAll) {
- if (!rsloaderRelocateExecutable(executable,
- art_find_runtime_support_func, NULL)) {
- LOG(ERROR) << "Failed to relocate the ELF image";
- rsloaderDisposeExec(executable);
- return false;
- }
- relocated = true;
- }
-
- executables_[elf_idx] = executable;
- elf_images_[elf_idx] = elf_image;
- return true;
-}
-
-
-void ElfLoader::RelocateExecutable() {
- if (relocated) {
- return;
- }
- LOG(INFO) << "Reload ELF for relocate.";
- for (size_t i = 0; i < executables_.size(); ++i) {
- if (executables_[i] != NULL) {
- // TODO: After implement in-place linking, we will no longer need to dispose and reload.
- rsloaderDisposeExec(executables_[i]);
- executables_[i] = rsloaderLoadExecutable(elf_images_[i].begin(), elf_images_[i].size(), 0);
- if (executables_[i] == NULL) {
- LOG(FATAL) << "Failed to reload ELF image " << i;
- }
- if (!rsloaderRelocateExecutable(executables_[i],
- art_find_runtime_support_func, NULL)) {
- LOG(FATAL) << "Failed to relocate ELF image " << i;
- }
- }
- }
- relocated = true;
-}
-
-
-const void* ElfLoader::GetMethodCodeAddr(uint16_t elf_idx,
- uint16_t elf_func_idx) const {
- CHECK_LT(elf_idx, executables_.size());
- return GetAddr(elf_idx, ElfFuncName(elf_func_idx).c_str());
-}
-
-
-const Method::InvokeStub* ElfLoader::
-GetMethodInvokeStubAddr(uint16_t elf_idx, uint16_t elf_func_idx) const {
- CHECK_LT(elf_idx, executables_.size());
- return reinterpret_cast<const Method::InvokeStub*>(
- GetAddr(elf_idx, ElfFuncName(elf_func_idx).c_str()));
-}
-
-
-size_t ElfLoader::GetCodeSize(uint16_t elf_idx, uint16_t elf_func_idx) const {
- CHECK_LT(elf_idx, executables_.size());
- CHECK(executables_[elf_idx] != NULL);
- return rsloaderGetSymbolSize(executables_[elf_idx],
- ElfFuncName(elf_func_idx).c_str());
-}
-
-
-const void* ElfLoader::GetAddr(size_t elf_idx, const char* sym_name) const {
- CHECK_LT(elf_idx, executables_.size());
- CHECK(executables_[elf_idx] != NULL);
- return rsloaderGetSymbolAddress(executables_[elf_idx], sym_name);
-}
-
-
-} // namespace compiler_llvm
-} // namespace art
diff --git a/src/compiler_llvm/elf_loader.h b/src/compiler_llvm/elf_loader.h
deleted file mode 100644
index 9e8611c..0000000
--- a/src/compiler_llvm/elf_loader.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2012 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_COMPILER_LLVM_ELF_LOADER_H_
-#define ART_SRC_COMPILER_LLVM_ELF_LOADER_H_
-
-#include "elf_image.h"
-#include "globals.h"
-#include "oat_file.h"
-#include "object.h"
-
-#include <android/librsloader.h>
-#include <vector>
-
-namespace art {
-namespace compiler_llvm {
-
-class ElfLoader {
- public:
- ElfLoader() : relocated(false) {}
- ~ElfLoader();
-
- bool LoadElfAt(size_t elf_idx, const ElfImage& elf_image,
- OatFile::RelocationBehavior reloc);
-
- void RelocateExecutable();
-
- const void* GetMethodCodeAddr(uint16_t elf_idx,
- uint16_t elf_func_idx) const;
-
- const Method::InvokeStub* GetMethodInvokeStubAddr(uint16_t elf_idx,
- uint16_t elf_func_idx) const;
-
- size_t GetCodeSize(uint16_t elf_idx, uint16_t elf_func_idx) const;
-
- private:
- const void* GetAddr(size_t elf_idx, const char* sym_name) const;
-
- bool relocated;
- std::vector<ElfImage> elf_images_;
- std::vector<RSExecRef> executables_;
-};
-
-
-} // namespace compiler_llvm
-} // namespace art
-
-#endif // ART_SRC_COMPILER_LLVM_ELF_LOADER_H_
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
index 37ca82f..f4f5be5 100644
--- a/src/compiler_llvm/jni_compiler.cc
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -51,8 +51,7 @@
class_loader_(oat_compilation_unit->class_loader_),
dex_cache_(oat_compilation_unit->dex_cache_),
dex_file_(oat_compilation_unit->dex_file_),
- method_(dex_cache_->GetResolvedMethod(method_idx_)),
- elf_func_idx_(cunit_->AcquireUniqueElfFuncIndex()) {
+ method_(dex_cache_->GetResolvedMethod(method_idx_)) {
// Check: Ensure that the method is resolved
CHECK_NE(method_, static_cast<art::Method*>(NULL));
@@ -262,26 +261,16 @@
// Verify the generated bitcode
VERIFY_LLVM_FUNCTION(*func_);
- // Add the memory usage approximation of the compilation unit
- cunit_->AddMemUsageApproximation((sirt_size * 4 + 50) * 50);
- // NOTE: We will emit 4 LLVM instructions per object argument,
- // And about 50 instructions for other operations. (Some runtime support will be inlined.)
- // Beside, we guess that we have to use 50 bytes to represent one LLVM instruction.
+ cunit_->Materialize();
- CompiledMethod* compiled_method =
- new CompiledMethod(cunit_->GetInstructionSet(),
- cunit_->GetElfIndex(),
- elf_func_idx_);
-
- cunit_->RegisterCompiledMethod(func_, compiled_method);
-
- return compiled_method;
+ return new CompiledMethod(cunit_->GetInstructionSet(),
+ cunit_->GetCompiledCode());
}
void JniCompiler::CreateFunction() {
// LLVM function name
- std::string func_name(ElfFuncName(elf_func_idx_));
+ std::string func_name(ElfFuncName(cunit_->GetIndex()));
// Get function type
llvm::FunctionType* func_type =
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index eef71db..da8f91a 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -72,8 +72,7 @@
basic_block_landing_pads_(code_item_->tries_size_, NULL),
basic_block_unwind_(NULL), basic_block_unreachable_(NULL),
shadow_frame_(NULL), old_shadow_frame_(NULL),
- already_pushed_shadow_frame_(NULL), shadow_frame_size_(0),
- elf_func_idx_(cunit_->AcquireUniqueElfFuncIndex()) {
+ already_pushed_shadow_frame_(NULL), shadow_frame_size_(0) {
}
@@ -84,7 +83,7 @@
void MethodCompiler::CreateFunction() {
// LLVM function name
- std::string func_name(ElfFuncName(elf_func_idx_));
+ std::string func_name(ElfFuncName(cunit_->GetIndex()));
// Get function type
llvm::FunctionType* func_type =
@@ -3616,20 +3615,10 @@
// Verify the generated bitcode
VERIFY_LLVM_FUNCTION(*func_);
- // Add the memory usage approximation of the compilation unit
- cunit_->AddMemUsageApproximation(code_item_->insns_size_in_code_units_ * 900);
- // NOTE: From statistics, the bitcode size is 4.5 times bigger than the
- // Dex file. Besides, we have to convert the code unit into bytes.
- // Thus, we got our magic number 9.
+ cunit_->Materialize();
- CompiledMethod* compiled_method =
- new CompiledMethod(cunit_->GetInstructionSet(),
- cunit_->GetElfIndex(),
- elf_func_idx_);
-
- cunit_->RegisterCompiledMethod(func_, compiled_method);
-
- return compiled_method;
+ return new CompiledMethod(cunit_->GetInstructionSet(),
+ cunit_->GetCompiledCode());
}
diff --git a/src/compiler_llvm/stub_compiler.cc b/src/compiler_llvm/stub_compiler.cc
index 0d64f0d..af05e52 100644
--- a/src/compiler_llvm/stub_compiler.cc
+++ b/src/compiler_llvm/stub_compiler.cc
@@ -48,13 +48,11 @@
CompiledInvokeStub* StubCompiler::CreateInvokeStub(bool is_static,
char const* shorty) {
- uint16_t elf_func_idx = cunit_->AcquireUniqueElfFuncIndex();
-
CHECK(shorty != NULL);
size_t shorty_size = strlen(shorty);
// Function name
- std::string func_name(ElfFuncName(elf_func_idx));
+ std::string func_name(ElfFuncName(cunit_->GetIndex()));
// Get argument types
llvm::Type* arg_types[] = {
@@ -186,15 +184,10 @@
// Verify the generated function
VERIFY_LLVM_FUNCTION(*func);
- // Add the memory usage approximation of the compilation unit
- cunit_->AddMemUsageApproximation((shorty_size * 3 + 8) * 50);
- // NOTE: We will emit 3 LLVM instructions per shorty for the argument,
- // plus 3 for pointer arithmetic, and 5 for code_addr, retval, ret_addr,
- // store ret_addr, and ret_void. Beside, we guess that we have to use
- // 50 bytes to represent one LLVM instruction.
+ cunit_->Materialize();
return new CompiledInvokeStub(cunit_->GetInstructionSet(),
- cunit_->GetElfIndex(), elf_func_idx);
+ cunit_->GetCompiledCode());
}
@@ -202,10 +195,8 @@
CHECK(shorty != NULL);
size_t shorty_size = strlen(shorty);
- uint16_t elf_func_idx = cunit_->AcquireUniqueElfFuncIndex();
-
// Function name
- std::string func_name(ElfFuncName(elf_func_idx));
+ std::string func_name(ElfFuncName(cunit_->GetIndex()));
// Accurate function type
llvm::Type* accurate_ret_type = irb_.getJType(shorty[0], kAccurate);
@@ -266,11 +257,10 @@
// Verify the generated function
VERIFY_LLVM_FUNCTION(*func);
- // Add the memory usage approximation of the compilation unit
- cunit_->AddMemUsageApproximation((shorty_size + 2) * 50);
+ cunit_->Materialize();
return new CompiledInvokeStub(cunit_->GetInstructionSet(),
- cunit_->GetElfIndex(), elf_func_idx);
+ cunit_->GetCompiledCode());
}
diff --git a/src/compiler_llvm/utils_llvm.h b/src/compiler_llvm/utils_llvm.h
index dd35f0a..eb5fd53 100644
--- a/src/compiler_llvm/utils_llvm.h
+++ b/src/compiler_llvm/utils_llvm.h
@@ -32,8 +32,8 @@
#define VERIFY_LLVM_FUNCTION(func)
#endif
-inline static std::string ElfFuncName(uint16_t elf_func_idx) {
- return StringPrintf("Art%u", static_cast<unsigned int>(elf_func_idx));
+inline static std::string ElfFuncName(uint16_t idx) {
+ return StringPrintf("Art%u", static_cast<unsigned int>(idx));
}
class CStringLessThanComparator {
diff --git a/src/elf_image.h b/src/elf_image.h
deleted file mode 100644
index 094467a..0000000
--- a/src/elf_image.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2012 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_ELF_IMAGE_H_
-#define ART_SRC_ELF_IMAGE_H_
-
-#include "globals.h"
-#include <string>
-#include <vector>
-
-namespace art {
-
-class ElfImage {
- public:
- explicit ElfImage(const std::vector<uint8_t>& v)
- : begin_(&*v.begin()), size_(v.size()) {
- }
-
- explicit ElfImage(const std::string& s)
- : begin_(reinterpret_cast<const uint8_t*>(s.data())), size_(s.size()) {
- }
-
- explicit ElfImage(const byte* begin, size_t size)
- : begin_(begin), size_(size) {
- }
-
- // TODO: Remove this after implement in-place linking.
- ElfImage() : begin_(NULL), size_(0) {
- }
-
- const byte* begin() const {
- return begin_;
- }
-
- const byte* end() const {
- return (begin_ + size_);
- }
-
- size_t size() const {
- return size_;
- }
-
- private:
- const byte* begin_;
- size_t size_;
-};
-
-} // namespace art
-
-#endif // ART_SRC_ELF_IMAGE_H_
diff --git a/src/oat.cc b/src/oat.cc
index ce7c133..cd9e0a3 100644
--- a/src/oat.cc
+++ b/src/oat.cc
@@ -29,7 +29,6 @@
OatHeader::OatHeader(InstructionSet instruction_set,
const std::vector<const DexFile*>* dex_files,
- uint32_t elf_image_count,
uint32_t image_file_location_checksum,
const std::string& image_file_location) {
memcpy(magic_, kOatMagic, sizeof(kOatMagic));
@@ -43,9 +42,6 @@
dex_file_count_ = dex_files->size();
UpdateChecksum(&dex_file_count_, sizeof(dex_file_count_));
- elf_image_count_ = elf_image_count;
- UpdateChecksum(&elf_image_count_, sizeof(elf_image_count_));
-
image_file_location_checksum_ = image_file_location_checksum;
UpdateChecksum(&image_file_location_checksum_, sizeof(image_file_location_checksum_));
@@ -53,7 +49,6 @@
UpdateChecksum(&image_file_location_size_, sizeof(image_file_location_size_));
UpdateChecksum(image_file_location.data(), image_file_location_size_);
- elf_image_table_offset_ = 0;
executable_offset_ = 0;
}
@@ -77,16 +72,6 @@
return dex_file_count_;
}
-uint32_t OatHeader::GetElfImageCount() const {
- DCHECK(IsValid());
- return elf_image_count_;
-}
-
-uint32_t OatHeader::GetElfImageTableOffset() const {
- DCHECK(IsValid());
- return elf_image_table_offset_;
-}
-
uint32_t OatHeader::GetChecksum() const {
CHECK(IsValid());
return adler32_checksum_;
@@ -131,12 +116,6 @@
GetImageFileLocationSize());
}
-void OatHeader::SetElfImageTableOffset(uint32_t elf_image_table_offset) {
- DCHECK(IsValid());
- elf_image_table_offset_ = elf_image_table_offset;
- UpdateChecksum(&elf_image_table_offset_, sizeof(elf_image_table_offset_));
-}
-
void OatHeader::SetExecutableOffset(uint32_t executable_offset) {
DCHECK_ALIGNED(executable_offset, kPageSize);
CHECK_GT(executable_offset, sizeof(OatHeader));
@@ -156,12 +135,6 @@
vmap_table_offset_(0),
gc_map_offset_(0),
invoke_stub_offset_(0)
-#if defined(ART_USE_LLVM_COMPILER)
- , code_elf_idx_(static_cast<uint16_t>(-1u)),
- code_elf_func_idx_(static_cast<uint16_t>(-1u)),
- invoke_stub_elf_idx_(static_cast<uint16_t>(-1u)),
- invoke_stub_elf_func_idx_(static_cast<uint16_t>(-1u))
-#endif
{}
OatMethodOffsets::OatMethodOffsets(uint32_t code_offset,
@@ -173,12 +146,7 @@
uint32_t gc_map_offset,
uint32_t invoke_stub_offset
#if defined(ART_USE_LLVM_COMPILER)
- , uint16_t code_elf_idx,
- uint16_t code_elf_func_idx,
- uint16_t invoke_stub_elf_idx,
- uint16_t invoke_stub_elf_func_idx,
- uint16_t proxy_stub_elf_idx,
- uint16_t proxy_stub_elf_func_idx
+ , uint32_t proxy_stub_offset
#endif
)
: code_offset_(code_offset),
@@ -190,12 +158,7 @@
gc_map_offset_(gc_map_offset),
invoke_stub_offset_(invoke_stub_offset)
#if defined(ART_USE_LLVM_COMPILER)
- , code_elf_idx_(code_elf_idx),
- code_elf_func_idx_(code_elf_func_idx),
- invoke_stub_elf_idx_(invoke_stub_elf_idx),
- invoke_stub_elf_func_idx_(invoke_stub_elf_func_idx),
- proxy_stub_elf_idx_(proxy_stub_elf_idx),
- proxy_stub_elf_func_idx_(proxy_stub_elf_func_idx)
+ , proxy_stub_offset_(proxy_stub_offset)
#endif
{}
diff --git a/src/oat.h b/src/oat.h
index d1e177f..cd3330b 100644
--- a/src/oat.h
+++ b/src/oat.h
@@ -30,7 +30,6 @@
OatHeader();
OatHeader(InstructionSet instruction_set,
const std::vector<const DexFile*>* dex_files,
- uint32_t elf_image_count,
uint32_t image_file_location_checksum,
const std::string& image_file_location);
@@ -39,11 +38,8 @@
uint32_t GetChecksum() const;
void UpdateChecksum(const void* data, size_t length);
uint32_t GetDexFileCount() const;
- uint32_t GetElfImageCount() const;
- uint32_t GetElfImageTableOffset() const;
uint32_t GetExecutableOffset() const;
InstructionSet GetInstructionSet() const;
- void SetElfImageTableOffset(uint32_t elf_image_offset);
void SetExecutableOffset(uint32_t executable_offset);
uint32_t GetImageFileLocationChecksum() const;
uint32_t GetImageFileLocationSize() const;
@@ -60,8 +56,6 @@
InstructionSet instruction_set_;
uint32_t dex_file_count_;
- uint32_t elf_image_count_;
- uint32_t elf_image_table_offset_;
uint32_t executable_offset_;
uint32_t image_file_location_checksum_;
@@ -74,6 +68,7 @@
class PACKED OatMethodOffsets {
public:
OatMethodOffsets();
+
OatMethodOffsets(uint32_t code_offset,
uint32_t frame_size_in_bytes,
uint32_t core_spill_mask,
@@ -83,14 +78,10 @@
uint32_t gc_map_offset,
uint32_t invoke_stub_offset
#if defined(ART_USE_LLVM_COMPILER)
- , uint16_t code_elf_idx,
- uint16_t code_elf_func_idx,
- uint16_t invoke_stub_elf_idx,
- uint16_t invoke_stub_elf_func_idx,
- uint16_t proxy_stub_elf_idx,
- uint16_t proxy_stub_elf_func_idx
+ , uint32_t proxy_stub_offset
#endif
);
+
~OatMethodOffsets();
uint32_t code_offset_;
@@ -103,12 +94,7 @@
uint32_t invoke_stub_offset_;
#if defined(ART_USE_LLVM_COMPILER)
- uint16_t code_elf_idx_;
- uint16_t code_elf_func_idx_;
- uint16_t invoke_stub_elf_idx_;
- uint16_t invoke_stub_elf_func_idx_;
- uint16_t proxy_stub_elf_idx_;
- uint16_t proxy_stub_elf_func_idx_;
+ uint32_t proxy_stub_offset_;
#endif
};
diff --git a/src/oat_file.cc b/src/oat_file.cc
index 239239b..f64f512 100644
--- a/src/oat_file.cc
+++ b/src/oat_file.cc
@@ -20,10 +20,6 @@
#include "os.h"
#include "stl_util.h"
-#if defined(ART_USE_LLVM_COMPILER)
-#include "compiler_llvm/elf_loader.h"
-#endif
-
namespace art {
std::string OatFile::DexFilenameToOatFilename(const std::string& location) {
@@ -64,19 +60,12 @@
}
OatFile::OatFile(const std::string& location)
- : location_(location)
-#if defined(ART_USE_LLVM_COMPILER)
- , elf_loader_(new compiler_llvm::ElfLoader())
-#endif
-{
+ : location_(location) {
CHECK(!location_.empty());
}
OatFile::~OatFile() {
STLDeleteValues(&oat_dex_files_);
-#if defined(ART_USE_LLVM_COMPILER)
- STLDeleteElements(&oat_elf_images_);
-#endif
}
bool OatFile::Map(File& file,
@@ -182,31 +171,6 @@
methods_offsets_pointer));
}
-#if !defined(ART_USE_LLVM_COMPILER)
- CHECK_EQ(oat_header.GetElfImageTableOffset(), 0u);
- CHECK_EQ(oat_header.GetElfImageCount(), 0u);
-
-#else
- oat = map->Begin() + oat_header.GetElfImageTableOffset();
- CHECK_EQ((reinterpret_cast<uintptr_t>(oat) & 0x3), 0u);
-
- for (uint32_t i = 0, end = oat_header.GetElfImageCount(); i < end; ++i) {
- uint32_t elf_offset = *reinterpret_cast<const uint32_t*>(oat);
- oat += sizeof(uint32_t);
-
- uint32_t elf_size = *reinterpret_cast<const uint32_t*>(oat);
- oat += sizeof(uint32_t);
-
- const byte* elf_begin = map->Begin() + elf_offset;
-
- oat_elf_images_.push_back(new OatElfImage(this, elf_begin, elf_size));
-
- if (!elf_loader_->LoadElfAt(i, ElfImage(elf_begin, elf_size), reloc)) {
- LOG(ERROR) << "Failed to load ELF image. index: " << i;
- }
- }
-#endif
-
mem_map_.reset(map.release());
return true;
}
@@ -246,9 +210,7 @@
}
void OatFile::RelocateExecutable() {
-#if defined(ART_USE_LLVM_COMPILER)
- elf_loader_->RelocateExecutable();
-#endif
+ UNIMPLEMENTED(WARNING) << "Relocate the executable";
}
OatFile::OatDexFile::OatDexFile(const OatFile* oat_file,
@@ -308,13 +270,7 @@
oat_method_offsets.gc_map_offset_,
oat_method_offsets.invoke_stub_offset_
#if defined(ART_USE_LLVM_COMPILER)
- , oat_file_->elf_loader_.get(),
- oat_method_offsets.code_elf_idx_,
- oat_method_offsets.code_elf_func_idx_,
- oat_method_offsets.invoke_stub_elf_idx_,
- oat_method_offsets.invoke_stub_elf_func_idx_,
- oat_method_offsets.proxy_stub_elf_idx_,
- oat_method_offsets.proxy_stub_elf_func_idx_
+ , oat_method_offsets.proxy_stub_offset_
#endif
);
}
@@ -329,13 +285,7 @@
const uint32_t gc_map_offset,
const uint32_t invoke_stub_offset
#if defined(ART_USE_LLVM_COMPILER)
- , const compiler_llvm::ElfLoader* elf_loader,
- const uint16_t code_elf_idx,
- const uint16_t code_elf_func_idx,
- const uint16_t invoke_stub_elf_idx,
- const uint16_t invoke_stub_elf_func_idx,
- const uint16_t proxy_stub_elf_idx,
- const uint16_t proxy_stub_elf_func_idx
+ , const uint32_t proxy_stub_offset
#endif
)
: begin_(base),
@@ -348,13 +298,7 @@
gc_map_offset_(gc_map_offset),
invoke_stub_offset_(invoke_stub_offset)
#if defined(ART_USE_LLVM_COMPILER)
- , elf_loader_(elf_loader),
- code_elf_idx_(code_elf_idx),
- code_elf_func_idx_(code_elf_func_idx),
- invoke_stub_elf_idx_(invoke_stub_elf_idx),
- invoke_stub_elf_func_idx_(invoke_stub_elf_func_idx),
- proxy_stub_elf_idx_(proxy_stub_elf_idx),
- proxy_stub_elf_func_idx_(proxy_stub_elf_func_idx)
+ , proxy_stub_offset_(proxy_stub_offset)
#endif
{
#ifndef NDEBUG
@@ -374,92 +318,37 @@
OatFile::OatMethod::~OatMethod() {}
const void* OatFile::OatMethod::GetCode() const {
- if (!IsCodeInElf()) {
- return GetOatPointer<const void*>(code_offset_);
- } else {
-#if !defined(ART_USE_LLVM_COMPILER)
- UNIMPLEMENTED(FATAL);
- return NULL;
-#else
- CHECK(elf_loader_ != NULL);
- const void* code =
- elf_loader_->GetMethodCodeAddr(code_elf_idx_, code_elf_func_idx_);
- CHECK(code != NULL);
- return code;
-#endif
- }
+ return GetOatPointer<const void*>(code_offset_);
}
uint32_t OatFile::OatMethod::GetCodeSize() const {
- if (!IsCodeInElf()) {
- uintptr_t code = reinterpret_cast<uint32_t>(GetCode());
+ uintptr_t code = reinterpret_cast<uint32_t>(GetCode());
- if (code == 0) {
- return 0;
- }
- // TODO: make this Thumb2 specific
- code &= ~0x1;
- return reinterpret_cast<uint32_t*>(code)[-1];
- } else {
-#if !defined(ART_USE_LLVM_COMPILER)
- UNIMPLEMENTED(ERROR);
+ if (code == 0) {
return 0;
-#else
- CHECK(elf_loader_ != NULL);
- return elf_loader_->GetCodeSize(code_elf_idx_, code_elf_func_idx_);
-#endif
}
+ // TODO: make this Thumb2 specific
+ code &= ~0x1;
+ return reinterpret_cast<uint32_t*>(code)[-1];
}
const Method::InvokeStub* OatFile::OatMethod::GetInvokeStub() const {
- if (!IsInvokeStubInElf()) {
- return GetOatPointer<const Method::InvokeStub*>(invoke_stub_offset_);
- } else {
-#if !defined(ART_USE_LLVM_COMPILER)
- UNIMPLEMENTED(FATAL);
- return NULL;
-#else
- CHECK(elf_loader_ != NULL);
- const Method::InvokeStub* stub =
- elf_loader_->GetMethodInvokeStubAddr(invoke_stub_elf_idx_,
- invoke_stub_elf_func_idx_);
- CHECK(stub != NULL);
- return stub;
-#endif
- }
+ return GetOatPointer<const Method::InvokeStub*>(invoke_stub_offset_);
}
uint32_t OatFile::OatMethod::GetInvokeStubSize() const {
- if (!IsInvokeStubInElf()) {
- uintptr_t code = reinterpret_cast<uint32_t>(GetInvokeStub());
- if (code == 0) {
- return 0;
- }
- // TODO: make this Thumb2 specific
- code &= ~0x1;
- return reinterpret_cast<uint32_t*>(code)[-1];
- } else {
-#if !defined(ART_USE_LLVM_COMPILER)
- UNIMPLEMENTED(WARNING);
+ uintptr_t code = reinterpret_cast<uint32_t>(GetInvokeStub());
+ if (code == 0) {
return 0;
-#else
- CHECK(elf_loader_ != NULL);
- return elf_loader_->GetCodeSize(invoke_stub_elf_idx_,
- invoke_stub_elf_func_idx_);
-#endif
}
+ // TODO: make this Thumb2 specific
+ code &= ~0x1;
+ return reinterpret_cast<uint32_t*>(code)[-1];
}
#if defined(ART_USE_LLVM_COMPILER)
const void* OatFile::OatMethod::GetProxyStub() const {
- CHECK(elf_loader_ != NULL);
- const void* stub = NULL;
- if (proxy_stub_elf_func_idx_ != static_cast<uint16_t>(-1)) {
- stub = elf_loader_->GetMethodCodeAddr(proxy_stub_elf_idx_,
- proxy_stub_elf_func_idx_);
- CHECK(stub != NULL);
- }
- return stub;
+ return GetOatPointer<const void*>(proxy_stub_offset_);
}
#endif
@@ -487,12 +376,4 @@
method->SetOatInvokeStubOffset(GetInvokeStubOffset());
}
-#if defined(ART_USE_LLVM_COMPILER)
-OatFile::OatElfImage::OatElfImage(const OatFile* oat_file,
- const byte* addr,
- uint32_t size)
- : oat_file_(oat_file), elf_addr_(addr), elf_size_(size) {
-}
-#endif
-
} // namespace art
diff --git a/src/oat_file.h b/src/oat_file.h
index a4ca2de..856a033 100644
--- a/src/oat_file.h
+++ b/src/oat_file.h
@@ -25,14 +25,6 @@
#include "oat.h"
#include "object.h"
-#if defined(ART_USE_LLVM_COMPILER)
-namespace art {
- namespace compiler_llvm {
- class ElfLoader;
- }
-}
-#endif
-
namespace art {
class OatFile {
@@ -103,37 +95,6 @@
return invoke_stub_offset_;
}
-#if defined(ART_USE_LLVM_COMPILER)
- uint16_t GetCodeElfIndex() const {
- return code_elf_idx_;
- }
- uint16_t GetCodeElfFuncIndex() const {
- return code_elf_func_idx_;
- }
- uint16_t GetInvokeStubElfIndex() const {
- return invoke_stub_elf_idx_;
- }
- uint16_t GetInvokeStubElfFuncIndex() const {
- return invoke_stub_elf_func_idx_;
- }
-#endif
-
- bool IsCodeInElf() const {
-#if defined(ART_USE_LLVM_COMPILER)
- return (code_elf_idx_ != static_cast<uint16_t>(-1));
-#else
- return false;
-#endif
- }
-
- bool IsInvokeStubInElf() const {
-#if defined(ART_USE_LLVM_COMPILER)
- return (invoke_stub_elf_idx_ != static_cast<uint16_t>(-1));
-#else
- return false;
-#endif
- }
-
const void* GetCode() const;
uint32_t GetCodeSize() const;
@@ -167,13 +128,7 @@
const uint32_t gc_map_offset,
const uint32_t invoke_stub_offset
#if defined(ART_USE_LLVM_COMPILER)
- , const compiler_llvm::ElfLoader* elf_loader,
- const uint16_t code_elf_idx,
- const uint16_t code_elf_func_idx,
- const uint16_t invoke_stub_elf_idx,
- const uint16_t invoke_stub_elf_func_idx,
- const uint16_t proxy_stub_elf_idx,
- const uint16_t proxy_stub_elf_func_idx
+ , const uint32_t proxy_stub_offset
#endif
);
@@ -198,14 +153,7 @@
uint32_t invoke_stub_offset_;
#if defined(ART_USE_LLVM_COMPILER)
- const compiler_llvm::ElfLoader* elf_loader_;
-
- uint16_t code_elf_idx_;
- uint16_t code_elf_func_idx_;
- uint16_t invoke_stub_elf_idx_;
- uint16_t invoke_stub_elf_func_idx_;
- uint16_t proxy_stub_elf_idx_;
- uint16_t proxy_stub_elf_func_idx_;
+ uint32_t proxy_stub_offset_;
#endif
friend class OatClass;
@@ -266,43 +214,10 @@
DISALLOW_COPY_AND_ASSIGN(OatDexFile);
};
-#if defined(ART_USE_LLVM_COMPILER)
- class OatElfImage {
- public:
- const byte* begin() const {
- return elf_addr_;
- }
-
- const byte* end() const {
- return (elf_addr_ + elf_size_);
- }
-
- size_t size() const {
- return elf_size_;
- }
-
- private:
- OatElfImage(const OatFile* oat_file, const byte* addr, uint32_t size);
-
- const OatFile* oat_file_;
- const byte* elf_addr_;
- uint32_t elf_size_;
-
- friend class OatFile;
- DISALLOW_COPY_AND_ASSIGN(OatElfImage);
- };
-#endif
-
const OatDexFile* GetOatDexFile(const std::string& dex_file_location,
bool warn_if_not_found = true) const;
std::vector<const OatDexFile*> GetOatDexFiles() const;
-#if defined(ART_USE_LLVM_COMPILER)
- const OatElfImage* GetOatElfImage(size_t i) const {
- return oat_elf_images_[i];
- }
-#endif
-
size_t Size() const {
return End() - Begin();
}
@@ -327,11 +242,6 @@
typedef SafeMap<std::string, const OatDexFile*> Table;
Table oat_dex_files_;
-#if defined(ART_USE_LLVM_COMPILER)
- std::vector<OatElfImage*> oat_elf_images_;
- UniquePtr<compiler_llvm::ElfLoader> elf_loader_;
-#endif
-
friend class OatClass;
friend class OatDexFile;
friend class OatDumper; // For GetBase and GetLimit
diff --git a/src/oat_writer.cc b/src/oat_writer.cc
index 2558eba..013a561 100644
--- a/src/oat_writer.cc
+++ b/src/oat_writer.cc
@@ -20,7 +20,6 @@
#include "class_linker.h"
#include "class_loader.h"
-#include "elf_image.h"
#include "file.h"
#include "os.h"
#include "safe_map.h"
@@ -53,15 +52,12 @@
image_file_location_checksum_ = image_file_location_checksum;
image_file_location_ = image_file_location;
dex_files_ = &dex_files;
- elf_images_ = compiler_->GetElfImages();
oat_header_ = NULL;
executable_offset_padding_length_ = 0;
size_t offset = InitOatHeader();
offset = InitOatDexFiles(offset);
offset = InitDexFiles(offset);
- offset = InitOatElfImages(offset);
- offset = InitElfImages(offset);
offset = InitOatClasses(offset);
offset = InitOatCode(offset);
offset = InitOatCodeDexFiles(offset);
@@ -72,7 +68,6 @@
OatWriter::~OatWriter() {
delete oat_header_;
STLDeleteElements(&oat_dex_files_);
- STLDeleteElements(&oat_elf_images_);
STLDeleteElements(&oat_classes_);
}
@@ -80,7 +75,6 @@
// create the OatHeader
oat_header_ = new OatHeader(compiler_->GetInstructionSet(),
dex_files_,
- elf_images_.size(),
image_file_location_checksum_,
image_file_location_);
size_t offset = sizeof(*oat_header_);
@@ -115,34 +109,6 @@
return offset;
}
-size_t OatWriter::InitOatElfImages(size_t offset) {
- size_t n = elf_images_.size();
- if (n != 0) {
- // Offset to ELF image table should be rounded up to 4-byte aligned, so that
- // we can read the uint32_t directly.
- offset = RoundUp(offset, 4);
- oat_header_->SetElfImageTableOffset(offset);
- } else {
- oat_header_->SetElfImageTableOffset(0);
- }
-
- for (size_t i = 0; i < n; ++i) {
- OatElfImage* oat_elf_image = new OatElfImage(elf_images_[i]);
- oat_elf_images_.push_back(oat_elf_image);
- offset += oat_elf_image->SizeOf();
- }
- return offset;
-}
-
-size_t OatWriter::InitElfImages(size_t offset) {
- for (size_t i = 0; i < oat_elf_images_.size(); ++i) {
- offset = RoundUp(offset, 4);
- oat_elf_images_[i]->SetElfOffset(offset);
- offset += oat_elf_images_[i]->GetElfSize();
- }
- return offset;
-}
-
size_t OatWriter::InitOatClasses(size_t offset) {
// create the OatClasses
// calculate the offsets within OatDexFiles to OatClasses
@@ -258,10 +224,6 @@
uint32_t method_idx, const DexFile* dex_file) {
// derived from CompiledMethod if available
uint32_t code_offset = 0;
-#if defined(ART_USE_LLVM_COMPILER)
- uint16_t code_elf_idx = static_cast<uint16_t>(-1u);
- uint16_t code_elf_func_idx = static_cast<uint16_t>(-1u);
-#endif
uint32_t frame_size_in_bytes = kStackAlignment;
uint32_t core_spill_mask = 0;
uint32_t fp_spill_mask = 0;
@@ -271,125 +233,107 @@
// derived from CompiledInvokeStub if available
uint32_t invoke_stub_offset = 0;
#if defined(ART_USE_LLVM_COMPILER)
- uint16_t invoke_stub_elf_idx = static_cast<uint16_t>(-1u);
- uint16_t invoke_stub_elf_func_idx = static_cast<uint16_t>(-1u);
- uint16_t proxy_stub_elf_idx = static_cast<uint16_t>(-1u);
- uint16_t proxy_stub_elf_func_idx = static_cast<uint16_t>(-1u);
+ uint32_t proxy_stub_offset = 0;
#endif
CompiledMethod* compiled_method =
compiler_->GetCompiledMethod(Compiler::MethodReference(dex_file, method_idx));
if (compiled_method != NULL) {
- if (compiled_method->IsExecutableInElf()) {
-#if defined(ART_USE_LLVM_COMPILER)
- code_elf_idx = compiled_method->GetElfIndex();
- code_elf_func_idx = compiled_method->GetElfFuncIndex();
-#endif
- frame_size_in_bytes = compiled_method->GetFrameSizeInBytes();
+ offset = compiled_method->AlignCode(offset);
+ DCHECK_ALIGNED(offset, kArmAlignment);
+ const std::vector<uint8_t>& code = compiled_method->GetCode();
+ uint32_t code_size = code.size() * sizeof(code[0]);
+ CHECK_NE(code_size, 0U);
+ uint32_t thumb_offset = compiled_method->CodeDelta();
+ code_offset = offset + sizeof(code_size) + thumb_offset;
+
+ // Deduplicate code arrays
+ SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code);
+ if (code_iter != code_offsets_.end()) {
+ code_offset = code_iter->second;
} else {
- offset = compiled_method->AlignCode(offset);
- DCHECK_ALIGNED(offset, kArmAlignment);
- const std::vector<uint8_t>& code = compiled_method->GetCode();
- uint32_t code_size = code.size() * sizeof(code[0]);
- CHECK_NE(code_size, 0U);
- uint32_t thumb_offset = compiled_method->CodeDelta();
- code_offset = offset + sizeof(code_size) + thumb_offset;
+ code_offsets_.Put(&code, code_offset);
+ offset += sizeof(code_size); // code size is prepended before code
+ offset += code_size;
+ oat_header_->UpdateChecksum(&code[0], code_size);
+ }
+ frame_size_in_bytes = compiled_method->GetFrameSizeInBytes();
+ core_spill_mask = compiled_method->GetCoreSpillMask();
+ fp_spill_mask = compiled_method->GetFpSpillMask();
- // Deduplicate code arrays
- SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code);
- if (code_iter != code_offsets_.end()) {
- code_offset = code_iter->second;
- } else {
- code_offsets_.Put(&code, code_offset);
- offset += sizeof(code_size); // code size is prepended before code
- offset += code_size;
- oat_header_->UpdateChecksum(&code[0], code_size);
- }
- frame_size_in_bytes = compiled_method->GetFrameSizeInBytes();
- core_spill_mask = compiled_method->GetCoreSpillMask();
- fp_spill_mask = compiled_method->GetFpSpillMask();
+ const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable();
+ size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]);
+ mapping_table_offset = (mapping_table_size == 0) ? 0 : offset;
- const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable();
- size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]);
- mapping_table_offset = (mapping_table_size == 0) ? 0 : offset;
+ // Deduplicate mapping tables
+ SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = mapping_table_offsets_.find(&mapping_table);
+ if (mapping_iter != mapping_table_offsets_.end()) {
+ mapping_table_offset = mapping_iter->second;
+ } else {
+ mapping_table_offsets_.Put(&mapping_table, mapping_table_offset);
+ offset += mapping_table_size;
+ oat_header_->UpdateChecksum(&mapping_table[0], mapping_table_size);
+ }
- // Deduplicate mapping tables
- SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter = mapping_table_offsets_.find(&mapping_table);
- if (mapping_iter != mapping_table_offsets_.end()) {
- mapping_table_offset = mapping_iter->second;
- } else {
- mapping_table_offsets_.Put(&mapping_table, mapping_table_offset);
- offset += mapping_table_size;
- oat_header_->UpdateChecksum(&mapping_table[0], mapping_table_size);
- }
+ const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable();
+ size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]);
+ vmap_table_offset = (vmap_table_size == 0) ? 0 : offset;
- const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable();
- size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]);
- vmap_table_offset = (vmap_table_size == 0) ? 0 : offset;
+ // Deduplicate vmap tables
+ SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = vmap_table_offsets_.find(&vmap_table);
+ if (vmap_iter != vmap_table_offsets_.end()) {
+ vmap_table_offset = vmap_iter->second;
+ } else {
+ vmap_table_offsets_.Put(&vmap_table, vmap_table_offset);
+ offset += vmap_table_size;
+ oat_header_->UpdateChecksum(&vmap_table[0], vmap_table_size);
+ }
- // Deduplicate vmap tables
- SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter = vmap_table_offsets_.find(&vmap_table);
- if (vmap_iter != vmap_table_offsets_.end()) {
- vmap_table_offset = vmap_iter->second;
- } else {
- vmap_table_offsets_.Put(&vmap_table, vmap_table_offset);
- offset += vmap_table_size;
- oat_header_->UpdateChecksum(&vmap_table[0], vmap_table_size);
- }
+ const std::vector<uint8_t>& gc_map = compiled_method->GetGcMap();
+ size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]);
+ gc_map_offset = (gc_map_size == 0) ? 0 : offset;
- const std::vector<uint8_t>& gc_map = compiled_method->GetGcMap();
- size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]);
- gc_map_offset = (gc_map_size == 0) ? 0 : offset;
-
-#ifndef NDEBUG
- // We expect GC maps except when the class hasn't been verified or the method is native
- CompiledClass* compiled_class =
- compiler_->GetCompiledClass(Compiler::MethodReference(dex_file, class_def_index));
- Class::Status status =
- (compiled_class != NULL) ? compiled_class->GetStatus() : Class::kStatusNotReady;
- CHECK(gc_map_size != 0 || is_native || status < Class::kStatusVerified)
- << &gc_map << " " << gc_map_size << " " << (is_native ? "true" : "false") << " " << (status < Class::kStatusVerified) << " " << status << " " << PrettyMethod(method_idx, *dex_file);
+#if !defined(NDEBUG) && !defined(ART_USE_LLVM_COMPILER)
+ // We expect GC maps except when the class hasn't been verified or the method is native
+ CompiledClass* compiled_class =
+ compiler_->GetCompiledClass(Compiler::MethodReference(dex_file, class_def_index));
+ Class::Status status =
+ (compiled_class != NULL) ? compiled_class->GetStatus() : Class::kStatusNotReady;
+ CHECK(gc_map_size != 0 || is_native || status < Class::kStatusVerified)
+ << &gc_map << " " << gc_map_size << " " << (is_native ? "true" : "false") << " " << (status < Class::kStatusVerified) << " " << status << " " << PrettyMethod(method_idx, *dex_file);
#endif
- // Deduplicate GC maps
- SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter = gc_map_offsets_.find(&gc_map);
- if (gc_map_iter != gc_map_offsets_.end()) {
- gc_map_offset = gc_map_iter->second;
- } else {
- gc_map_offsets_.Put(&gc_map, gc_map_offset);
- offset += gc_map_size;
- oat_header_->UpdateChecksum(&gc_map[0], gc_map_size);
- }
+ // Deduplicate GC maps
+ SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter = gc_map_offsets_.find(&gc_map);
+ if (gc_map_iter != gc_map_offsets_.end()) {
+ gc_map_offset = gc_map_iter->second;
+ } else {
+ gc_map_offsets_.Put(&gc_map, gc_map_offset);
+ offset += gc_map_size;
+ oat_header_->UpdateChecksum(&gc_map[0], gc_map_size);
}
}
const char* shorty = dex_file->GetMethodShorty(dex_file->GetMethodId(method_idx));
const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(is_static, shorty);
if (compiled_invoke_stub != NULL) {
- if (compiled_invoke_stub->IsExecutableInElf()) {
-#if defined(ART_USE_LLVM_COMPILER)
- invoke_stub_elf_idx = compiled_invoke_stub->GetElfIndex();
- invoke_stub_elf_func_idx = compiled_invoke_stub->GetElfFuncIndex();
-#endif
- } else {
- offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet());
- DCHECK_ALIGNED(offset, kArmAlignment);
- const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
- uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]);
- CHECK_NE(invoke_stub_size, 0U);
- uint32_t thumb_offset = compiled_invoke_stub->CodeDelta();
- invoke_stub_offset = offset + sizeof(invoke_stub_size) + thumb_offset;
+ offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet());
+ DCHECK_ALIGNED(offset, kArmAlignment);
+ const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
+ uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]);
+ CHECK_NE(invoke_stub_size, 0U);
+ uint32_t thumb_offset = compiled_invoke_stub->CodeDelta();
+ invoke_stub_offset = offset + sizeof(invoke_stub_size) + thumb_offset;
- // Deduplicate invoke stubs
- SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&invoke_stub);
- if (stub_iter != code_offsets_.end()) {
- invoke_stub_offset = stub_iter->second;
- } else {
- code_offsets_.Put(&invoke_stub, invoke_stub_offset);
- offset += sizeof(invoke_stub_size); // invoke stub size is prepended before code
- offset += invoke_stub_size;
- oat_header_->UpdateChecksum(&invoke_stub[0], invoke_stub_size);
- }
+ // Deduplicate invoke stubs
+ SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&invoke_stub);
+ if (stub_iter != code_offsets_.end()) {
+ invoke_stub_offset = stub_iter->second;
+ } else {
+ code_offsets_.Put(&invoke_stub, invoke_stub_offset);
+ offset += sizeof(invoke_stub_size); // invoke stub size is prepended before code
+ offset += invoke_stub_size;
+ oat_header_->UpdateChecksum(&invoke_stub[0], invoke_stub_size);
}
}
@@ -397,9 +341,24 @@
if (!is_static) {
const CompiledInvokeStub* compiled_proxy_stub = compiler_->FindProxyStub(shorty);
if (compiled_proxy_stub != NULL) {
- DCHECK(compiled_proxy_stub->IsExecutableInElf());
- proxy_stub_elf_idx = compiled_proxy_stub->GetElfIndex();
- proxy_stub_elf_func_idx = compiled_proxy_stub->GetElfFuncIndex();
+ offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet());
+ DCHECK_ALIGNED(offset, kArmAlignment);
+ const std::vector<uint8_t>& proxy_stub = compiled_proxy_stub->GetCode();
+ uint32_t proxy_stub_size = proxy_stub.size() * sizeof(proxy_stub[0]);
+ CHECK_NE(proxy_stub_size, 0U);
+ uint32_t thumb_offset = compiled_proxy_stub->CodeDelta();
+ proxy_stub_offset = offset + sizeof(proxy_stub_size) + thumb_offset;
+
+ // Deduplicate proxy stubs
+ SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&proxy_stub);
+ if (stub_iter != code_offsets_.end()) {
+ proxy_stub_offset = stub_iter->second;
+ } else {
+ code_offsets_.Put(&proxy_stub, proxy_stub_offset);
+ offset += sizeof(proxy_stub_size); // proxy stub size is prepended before code
+ offset += proxy_stub_size;
+ oat_header_->UpdateChecksum(&proxy_stub[0], proxy_stub_size);
+ }
}
}
#endif
@@ -414,12 +373,7 @@
gc_map_offset,
invoke_stub_offset
#if defined(ART_USE_LLVM_COMPILER)
- , code_elf_idx,
- code_elf_func_idx,
- invoke_stub_elf_idx,
- invoke_stub_elf_func_idx,
- proxy_stub_elf_idx,
- proxy_stub_elf_func_idx
+ , proxy_stub_offset
#endif
);
@@ -505,25 +459,6 @@
return false;
}
}
- for (size_t i = 0; i != oat_elf_images_.size(); ++i) {
- if (!oat_elf_images_[i]->Write(file)) {
- PLOG(ERROR) << "Failed to write oat elf information to " << file->name();
- return false;
- }
- }
- for (size_t i = 0; i != oat_elf_images_.size(); ++i) {
- uint32_t expected_offset = oat_elf_images_[i]->GetElfOffset();
- off_t actual_offset = lseek(file->Fd(), expected_offset, SEEK_SET);
- if (static_cast<uint32_t>(actual_offset) != expected_offset) {
- PLOG(ERROR) << "Failed to seek to dex file section."
- << " Actual: " << actual_offset
- << " Expected: " << expected_offset;
- return false;
- }
- if (!oat_elf_images_[i]->WriteElfImage(file)) {
- return false;
- }
- }
for (size_t i = 0; i != oat_classes_.size(); ++i) {
if (!oat_classes_[i]->Write(file)) {
PLOG(ERROR) << "Failed to write oat methods information to " << file->name();
@@ -629,126 +564,169 @@
if (compiled_method != NULL) { // ie. not an abstract method
- if (!compiled_method->IsExecutableInElf()) {
- uint32_t aligned_code_offset = compiled_method->AlignCode(code_offset);
- uint32_t aligned_code_delta = aligned_code_offset - code_offset;
- if (aligned_code_delta != 0) {
- off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR);
- if (static_cast<uint32_t>(new_offset) != aligned_code_offset) {
- PLOG(ERROR) << "Failed to seek to align oat code. Actual: " << new_offset
- << " Expected: " << aligned_code_offset << " File: " << file->name();
- return 0;
- }
- code_offset += aligned_code_delta;
- DCHECK_CODE_OFFSET();
+ uint32_t aligned_code_offset = compiled_method->AlignCode(code_offset);
+ uint32_t aligned_code_delta = aligned_code_offset - code_offset;
+ if (aligned_code_delta != 0) {
+ off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR);
+ if (static_cast<uint32_t>(new_offset) != aligned_code_offset) {
+ PLOG(ERROR) << "Failed to seek to align oat code. Actual: " << new_offset
+ << " Expected: " << aligned_code_offset << " File: " << file->name();
+ return 0;
}
- DCHECK_ALIGNED(code_offset, kArmAlignment);
- const std::vector<uint8_t>& code = compiled_method->GetCode();
- uint32_t code_size = code.size() * sizeof(code[0]);
- CHECK_NE(code_size, 0U);
-
- // Deduplicate code arrays
- size_t offset = code_offset + sizeof(code_size) + compiled_method->CodeDelta();
- SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code);
- if (code_iter != code_offsets_.end() && offset != method_offsets.code_offset_) {
- DCHECK(code_iter->second == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file);
- } else {
- DCHECK(offset == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file);
- if (!file->WriteFully(&code_size, sizeof(code_size))) {
- ReportWriteFailure("method code size", method_idx, dex_file, file);
- return 0;
- }
- code_offset += sizeof(code_size);
- DCHECK_CODE_OFFSET();
- if (!file->WriteFully(&code[0], code_size)) {
- ReportWriteFailure("method code", method_idx, dex_file, file);
- return 0;
- }
- code_offset += code_size;
- }
- DCHECK_CODE_OFFSET();
-
- const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable();
- size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]);
-
- // Deduplicate mapping tables
- SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter =
- mapping_table_offsets_.find(&mapping_table);
- if (mapping_iter != mapping_table_offsets_.end() &&
- code_offset != method_offsets.mapping_table_offset_) {
- DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0)
- || mapping_iter->second == method_offsets.mapping_table_offset_)
- << PrettyMethod(method_idx, dex_file);
- } else {
- DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0)
- || code_offset == method_offsets.mapping_table_offset_)
- << PrettyMethod(method_idx, dex_file);
- if (!file->WriteFully(&mapping_table[0], mapping_table_size)) {
- ReportWriteFailure("mapping table", method_idx, dex_file, file);
- return 0;
- }
- code_offset += mapping_table_size;
- }
- DCHECK_CODE_OFFSET();
-
- const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable();
- size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]);
-
- // Deduplicate vmap tables
- SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter =
- vmap_table_offsets_.find(&vmap_table);
- if (vmap_iter != vmap_table_offsets_.end() &&
- code_offset != method_offsets.vmap_table_offset_) {
- DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0)
- || vmap_iter->second == method_offsets.vmap_table_offset_)
- << PrettyMethod(method_idx, dex_file);
- } else {
- DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0)
- || code_offset == method_offsets.vmap_table_offset_)
- << PrettyMethod(method_idx, dex_file);
- if (!file->WriteFully(&vmap_table[0], vmap_table_size)) {
- ReportWriteFailure("vmap table", method_idx, dex_file, file);
- return 0;
- }
- code_offset += vmap_table_size;
- }
- DCHECK_CODE_OFFSET();
-
- const std::vector<uint8_t>& gc_map = compiled_method->GetGcMap();
- size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]);
-
- // Deduplicate GC maps
- SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter =
- gc_map_offsets_.find(&gc_map);
- if (gc_map_iter != gc_map_offsets_.end() &&
- code_offset != method_offsets.gc_map_offset_) {
- DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0)
- || gc_map_iter->second == method_offsets.gc_map_offset_)
- << PrettyMethod(method_idx, dex_file);
- } else {
- DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0)
- || code_offset == method_offsets.gc_map_offset_)
- << PrettyMethod(method_idx, dex_file);
- if (!file->WriteFully(&gc_map[0], gc_map_size)) {
- ReportWriteFailure("GC map", method_idx, dex_file, file);
- return 0;
- }
- code_offset += gc_map_size;
- }
+ code_offset += aligned_code_delta;
DCHECK_CODE_OFFSET();
}
+ DCHECK_ALIGNED(code_offset, kArmAlignment);
+ const std::vector<uint8_t>& code = compiled_method->GetCode();
+ uint32_t code_size = code.size() * sizeof(code[0]);
+ CHECK_NE(code_size, 0U);
+
+ // Deduplicate code arrays
+ size_t offset = code_offset + sizeof(code_size) + compiled_method->CodeDelta();
+ SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter = code_offsets_.find(&code);
+ if (code_iter != code_offsets_.end() && offset != method_offsets.code_offset_) {
+ DCHECK(code_iter->second == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file);
+ } else {
+ DCHECK(offset == method_offsets.code_offset_) << PrettyMethod(method_idx, dex_file);
+ if (!file->WriteFully(&code_size, sizeof(code_size))) {
+ ReportWriteFailure("method code size", method_idx, dex_file, file);
+ return 0;
+ }
+ code_offset += sizeof(code_size);
+ DCHECK_CODE_OFFSET();
+ if (!file->WriteFully(&code[0], code_size)) {
+ ReportWriteFailure("method code", method_idx, dex_file, file);
+ return 0;
+ }
+ code_offset += code_size;
+ }
+ DCHECK_CODE_OFFSET();
+
+ const std::vector<uint32_t>& mapping_table = compiled_method->GetMappingTable();
+ size_t mapping_table_size = mapping_table.size() * sizeof(mapping_table[0]);
+
+ // Deduplicate mapping tables
+ SafeMap<const std::vector<uint32_t>*, uint32_t>::iterator mapping_iter =
+ mapping_table_offsets_.find(&mapping_table);
+ if (mapping_iter != mapping_table_offsets_.end() &&
+ code_offset != method_offsets.mapping_table_offset_) {
+ DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0)
+ || mapping_iter->second == method_offsets.mapping_table_offset_)
+ << PrettyMethod(method_idx, dex_file);
+ } else {
+ DCHECK((mapping_table_size == 0 && method_offsets.mapping_table_offset_ == 0)
+ || code_offset == method_offsets.mapping_table_offset_)
+ << PrettyMethod(method_idx, dex_file);
+ if (!file->WriteFully(&mapping_table[0], mapping_table_size)) {
+ ReportWriteFailure("mapping table", method_idx, dex_file, file);
+ return 0;
+ }
+ code_offset += mapping_table_size;
+ }
+ DCHECK_CODE_OFFSET();
+
+ const std::vector<uint16_t>& vmap_table = compiled_method->GetVmapTable();
+ size_t vmap_table_size = vmap_table.size() * sizeof(vmap_table[0]);
+
+ // Deduplicate vmap tables
+ SafeMap<const std::vector<uint16_t>*, uint32_t>::iterator vmap_iter =
+ vmap_table_offsets_.find(&vmap_table);
+ if (vmap_iter != vmap_table_offsets_.end() &&
+ code_offset != method_offsets.vmap_table_offset_) {
+ DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0)
+ || vmap_iter->second == method_offsets.vmap_table_offset_)
+ << PrettyMethod(method_idx, dex_file);
+ } else {
+ DCHECK((vmap_table_size == 0 && method_offsets.vmap_table_offset_ == 0)
+ || code_offset == method_offsets.vmap_table_offset_)
+ << PrettyMethod(method_idx, dex_file);
+ if (!file->WriteFully(&vmap_table[0], vmap_table_size)) {
+ ReportWriteFailure("vmap table", method_idx, dex_file, file);
+ return 0;
+ }
+ code_offset += vmap_table_size;
+ }
+ DCHECK_CODE_OFFSET();
+
+ const std::vector<uint8_t>& gc_map = compiled_method->GetGcMap();
+ size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]);
+
+ // Deduplicate GC maps
+ SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator gc_map_iter =
+ gc_map_offsets_.find(&gc_map);
+ if (gc_map_iter != gc_map_offsets_.end() &&
+ code_offset != method_offsets.gc_map_offset_) {
+ DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0)
+ || gc_map_iter->second == method_offsets.gc_map_offset_)
+ << PrettyMethod(method_idx, dex_file);
+ } else {
+ DCHECK((gc_map_size == 0 && method_offsets.gc_map_offset_ == 0)
+ || code_offset == method_offsets.gc_map_offset_)
+ << PrettyMethod(method_idx, dex_file);
+ if (!file->WriteFully(&gc_map[0], gc_map_size)) {
+ ReportWriteFailure("GC map", method_idx, dex_file, file);
+ return 0;
+ }
+ code_offset += gc_map_size;
+ }
+ DCHECK_CODE_OFFSET();
}
const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx));
const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(is_static, shorty);
if (compiled_invoke_stub != NULL) {
- if (!compiled_invoke_stub->IsExecutableInElf()) {
+ uint32_t aligned_code_offset = CompiledMethod::AlignCode(code_offset,
+ compiler_->GetInstructionSet());
+ uint32_t aligned_code_delta = aligned_code_offset - code_offset;
+ if (aligned_code_delta != 0) {
+ off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR);
+ if (static_cast<uint32_t>(new_offset) != aligned_code_offset) {
+ PLOG(ERROR) << "Failed to seek to align invoke stub code. Actual: " << new_offset
+ << " Expected: " << aligned_code_offset;
+ return 0;
+ }
+ code_offset += aligned_code_delta;
+ DCHECK_CODE_OFFSET();
+ }
+ DCHECK_ALIGNED(code_offset, kArmAlignment);
+ const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
+ uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]);
+ CHECK_NE(invoke_stub_size, 0U);
+
+ // Deduplicate invoke stubs
+ size_t offset = code_offset + sizeof(invoke_stub_size) + compiled_invoke_stub->CodeDelta();
+ SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter =
+ code_offsets_.find(&invoke_stub);
+ if (stub_iter != code_offsets_.end() && offset != method_offsets.invoke_stub_offset_) {
+ DCHECK(stub_iter->second == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file);
+ } else {
+ DCHECK(offset == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file);
+ if (!file->WriteFully(&invoke_stub_size, sizeof(invoke_stub_size))) {
+ ReportWriteFailure("invoke stub code size", method_idx, dex_file, file);
+ return 0;
+ }
+ code_offset += sizeof(invoke_stub_size);
+ DCHECK_CODE_OFFSET();
+ if (!file->WriteFully(&invoke_stub[0], invoke_stub_size)) {
+ ReportWriteFailure("invoke stub code", method_idx, dex_file, file);
+ return 0;
+ }
+ code_offset += invoke_stub_size;
+ DCHECK_CODE_OFFSET();
+ }
+ }
+
+#if defined(ART_USE_LLVM_COMPILER)
+ if (!is_static) {
+ const CompiledInvokeStub* compiled_proxy_stub = compiler_->FindProxyStub(shorty);
+ if (compiled_proxy_stub != NULL) {
uint32_t aligned_code_offset = CompiledMethod::AlignCode(code_offset,
compiler_->GetInstructionSet());
uint32_t aligned_code_delta = aligned_code_offset - code_offset;
+ CHECK(aligned_code_delta < 48u);
if (aligned_code_delta != 0) {
off_t new_offset = lseek(file->Fd(), aligned_code_delta, SEEK_CUR);
if (static_cast<uint32_t>(new_offset) != aligned_code_offset) {
- PLOG(ERROR) << "Failed to seek to align invoke stub code. Actual: " << new_offset
+ PLOG(ERROR) << "Failed to seek to align proxy stub code. Actual: " << new_offset
<< " Expected: " << aligned_code_offset;
return 0;
}
@@ -756,33 +734,35 @@
DCHECK_CODE_OFFSET();
}
DCHECK_ALIGNED(code_offset, kArmAlignment);
- const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
- uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]);
- CHECK_NE(invoke_stub_size, 0U);
+ const std::vector<uint8_t>& proxy_stub = compiled_proxy_stub->GetCode();
+ uint32_t proxy_stub_size = proxy_stub.size() * sizeof(proxy_stub[0]);
+ CHECK_NE(proxy_stub_size, 0U);
- // Deduplicate invoke stubs
- size_t offset = code_offset + sizeof(invoke_stub_size) + compiled_invoke_stub->CodeDelta();
+ // Deduplicate proxy stubs
+ size_t offset = code_offset + sizeof(proxy_stub_size) + compiled_proxy_stub->CodeDelta();
SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter =
- code_offsets_.find(&invoke_stub);
- if (stub_iter != code_offsets_.end() && offset != method_offsets.invoke_stub_offset_) {
- DCHECK(stub_iter->second == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file);
+ code_offsets_.find(&proxy_stub);
+ if (stub_iter != code_offsets_.end() && offset != method_offsets.proxy_stub_offset_) {
+ DCHECK(stub_iter->second == method_offsets.proxy_stub_offset_) << PrettyMethod(method_idx, dex_file);
} else {
- DCHECK(offset == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file);
- if (!file->WriteFully(&invoke_stub_size, sizeof(invoke_stub_size))) {
- ReportWriteFailure("invoke stub code size", method_idx, dex_file, file);
+ DCHECK(offset == method_offsets.proxy_stub_offset_) << PrettyMethod(method_idx, dex_file);
+ if (!file->WriteFully(&proxy_stub_size, sizeof(proxy_stub_size))) {
+ ReportWriteFailure("proxy stub code size", method_idx, dex_file, file);
return 0;
}
- code_offset += sizeof(invoke_stub_size);
+ code_offset += sizeof(proxy_stub_size);
DCHECK_CODE_OFFSET();
- if (!file->WriteFully(&invoke_stub[0], invoke_stub_size)) {
- ReportWriteFailure("invoke stub code", method_idx, dex_file, file);
+ if (!file->WriteFully(&proxy_stub[0], proxy_stub_size)) {
+ ReportWriteFailure("proxy stub code", method_idx, dex_file, file);
return 0;
}
- code_offset += invoke_stub_size;
+ code_offset += proxy_stub_size;
+ DCHECK_CODE_OFFSET();
}
DCHECK_CODE_OFFSET();
}
}
+#endif
return code_offset;
}
@@ -867,48 +847,4 @@
return true;
}
-OatWriter::OatElfImage::OatElfImage(const ElfImage& image)
- : elf_offset_(0), elf_size_(image.size()), elf_addr_(image.begin()) {
-}
-
-size_t OatWriter::OatElfImage::SizeOf() const {
- return (sizeof(elf_offset_) + sizeof(elf_size_));
-}
-
-uint32_t OatWriter::OatElfImage::GetElfSize() const {
- return elf_size_;
-}
-
-uint32_t OatWriter::OatElfImage::GetElfOffset() const {
- DCHECK_NE(elf_offset_, 0U);
- return elf_offset_;
-}
-
-void OatWriter::OatElfImage::SetElfOffset(uint32_t offset) {
- DCHECK_NE(offset, 0U);
- DCHECK_EQ((offset & 0x3LU), 0U);
- elf_offset_ = offset;
-}
-
-bool OatWriter::OatElfImage::Write(File* file) const {
- DCHECK_NE(elf_offset_, 0U);
- if (!file->WriteFully(&elf_offset_, sizeof(elf_offset_))) {
- PLOG(ERROR) << "Failed to write ELF offset to " << file->name();
- return false;
- }
- if (!file->WriteFully(&elf_size_, sizeof(elf_size_))) {
- PLOG(ERROR) << "Failed to write ELF size to " << file->name();
- return false;
- }
- return true;
-}
-
-bool OatWriter::OatElfImage::WriteElfImage(File* file) const {
- if (!file->WriteFully(elf_addr_, elf_size_)) {
- PLOG(ERROR) << "Failed to write ELF image to " << file->name();
- return false;
- }
- return true;
-}
-
} // namespace art
diff --git a/src/oat_writer.h b/src/oat_writer.h
index 29072ab..b748dbc 100644
--- a/src/oat_writer.h
+++ b/src/oat_writer.h
@@ -49,16 +49,6 @@
// ...
// OatClass[C]
//
-// OatElfImage[0] one OatElfImage for each ELF image
-// OatElfImage[1] contains the size, checksum, and offset to the ELF image.
-// ...
-// OatElfImage[E]
-//
-// ELF[0]
-// ELF[1]
-// ...
-// ELF[E]
-//
// padding if necessary so that the following code will be page aligned
//
// CompiledMethod one variable sized blob with the contents of each CompiledMethod
@@ -92,8 +82,6 @@
size_t InitOatDexFiles(size_t offset);
size_t InitDexFiles(size_t offset);
size_t InitOatClasses(size_t offset);
- size_t InitOatElfImages(size_t offset);
- size_t InitElfImages(size_t offset);
size_t InitOatCode(size_t offset);
size_t InitOatCodeDexFiles(size_t offset);
size_t InitOatCodeDexFile(size_t offset,
@@ -155,25 +143,6 @@
DISALLOW_COPY_AND_ASSIGN(OatClass);
};
- class OatElfImage {
- public:
- explicit OatElfImage(const ElfImage& elf_image);
- size_t SizeOf() const;
- uint32_t GetElfSize() const;
- uint32_t GetElfOffset() const;
- void SetElfOffset(uint32_t offset);
- bool Write(File* file) const;
- bool WriteElfImage(File* file) const;
-
- private:
- // data to write
- uint32_t elf_offset_;
- const uint32_t elf_size_;
-
- const byte* const elf_addr_;
- DISALLOW_COPY_AND_ASSIGN(OatElfImage);
- };
-
const Compiler* compiler_;
// TODO: remove the ClassLoader when the code storage moves out of Method
@@ -182,8 +151,6 @@
// note OatFile does not take ownership of the DexFiles
const std::vector<const DexFile*>* dex_files_;
- std::vector<ElfImage> elf_images_;
-
// dependency on the image
uint32_t image_file_location_checksum_;
std::string image_file_location_;
@@ -192,7 +159,6 @@
OatHeader* oat_header_;
std::vector<OatDexFile*> oat_dex_files_;
std::vector<OatClass*> oat_classes_;
- std::vector<OatElfImage*> oat_elf_images_;
uint32_t executable_offset_padding_length_;
template <class T> struct MapCompare {
diff --git a/src/oatdump.cc b/src/oatdump.cc
index b599eaa..a33cd09 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -57,11 +57,6 @@
" Example: --boot-image=/system/framework/boot.art\n"
"\n");
fprintf(stderr,
- " --extract-elf-to=<file.elf>: provide the prefix of the filename for\n"
- " the output ELF files.\n"
- " Example: --extract-elf-to=output.elf\n"
- "\n");
- fprintf(stderr,
" --host-prefix may be used to translate host paths to target paths during\n"
" cross compilation.\n"
" Example: --host-prefix=out/target/product/crespo\n"
@@ -113,9 +108,6 @@
os << "DEX FILE COUNT:\n";
os << oat_header.GetDexFileCount() << "\n\n";
- os << "ELF IMAGE COUNT:\n";
- os << oat_header.GetElfImageCount() << "\n\n";
-
os << "EXECUTABLE OFFSET:\n";
os << StringPrintf("0x%08x\n\n", oat_header.GetExecutableOffset());
@@ -318,35 +310,17 @@
os << StringPrintf("\t\tgc_map: %p (offset=0x%08x)\n",
oat_method.GetGcMap(), oat_method.GetGcMapOffset());
DumpGcMap(os, oat_method.GetGcMap());
- os << StringPrintf(
-#if defined(ART_USE_LLVM_COMPILER)
- "\t\tCODE: %p (offset=0x%08x size=%d elf_idx=%d elf_func_idx=%d)%s\n",
-#else
- "\t\tCODE: %p (offset=0x%08x size=%d)%s\n",
-#endif
+ os << StringPrintf("\t\tCODE: %p (offset=0x%08x size=%d)%s\n",
oat_method.GetCode(),
oat_method.GetCodeOffset(),
oat_method.GetCodeSize(),
-#if defined(ART_USE_LLVM_COMPILER)
- static_cast<int>(oat_method.GetCodeElfIndex()),
- static_cast<int>(oat_method.GetCodeElfFuncIndex()),
-#endif
oat_method.GetCode() != NULL ? "..." : "");
DumpCode(os, oat_method.GetCode(), oat_method.GetCodeSize(), oat_method.GetMappingTable(),
dex_file, code_item);
- os << StringPrintf(
-#if defined(ART_USE_LLVM_COMPILER)
- "\t\tINVOKE STUB: %p (offset=0x%08x size=%d elf_idx=%d elf_func_idx=%d)%s\n",
-#else
- "\t\tINVOKE STUB: %p (offset=0x%08x size=%d)%s\n",
-#endif
+ os << StringPrintf("\t\tINVOKE STUB: %p (offset=0x%08x size=%d)%s\n",
oat_method.GetInvokeStub(),
oat_method.GetInvokeStubOffset(),
oat_method.GetInvokeStubSize(),
-#if defined(ART_USE_LLVM_COMPILER)
- static_cast<int>(oat_method.GetInvokeStubElfIndex()),
- static_cast<int>(oat_method.GetInvokeStubElfFuncIndex()),
-#endif
oat_method.GetInvokeStub() != NULL ? "..." : "");
DumpCode(os, reinterpret_cast<const void*>(oat_method.GetInvokeStub()),
oat_method.GetInvokeStubSize(), NULL, dex_file, NULL);
@@ -1158,8 +1132,6 @@
image_filename = option.substr(strlen("--image=")).data();
} else if (option.starts_with("--boot-image=")) {
boot_image_filename = option.substr(strlen("--boot-image=")).data();
- } else if (option.starts_with("--extract-elf-to=")) {
- elf_filename_prefix = option.substr(strlen("--extract-elf-to=")).data();
} else if (option.starts_with("--host-prefix=")) {
host_prefix.reset(new std::string(option.substr(strlen("--host-prefix=")).data()));
} else if (option.starts_with("--output=")) {
@@ -1204,25 +1176,6 @@
}
OatDumper oat_dumper(*host_prefix.get(), *oat_file);
oat_dumper.Dump(*os);
-
-#if defined(ART_USE_LLVM_COMPILER)
- if (!elf_filename_prefix.empty()) {
- uint32_t elf_image_count = oat_file->GetOatHeader().GetElfImageCount();
- for (uint32_t i = 0; i < elf_image_count; ++i) {
- const OatFile::OatElfImage* elf_image = oat_file->GetOatElfImage(i);
-
- std::string elf_filename(
- StringPrintf("%s-%u", elf_filename_prefix.c_str(), i));
-
- UniquePtr<File> elf_file(OS::OpenFile(elf_filename.c_str(), true));
-
- if (!elf_file->WriteFully(elf_image->begin(), elf_image->size())) {
- fprintf(stderr, "Failed to write ELF image to: %s\n",
- elf_filename.c_str());
- }
- }
- }
-#endif
return EXIT_SUCCESS;
}
diff --git a/src/runtime.cc b/src/runtime.cc
index 5f20a4b..b5928b2 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -48,6 +48,10 @@
#include "verifier/method_verifier.h"
#include "well_known_classes.h"
+#if defined(ART_USE_LLVM_COMPILER)
+#include "compiler_llvm/procedure_linkage_table.h"
+#endif
+
#include "JniConstants.h" // Last to avoid LOG redefinition in ics-mr1-plus-art.
namespace art {
@@ -83,13 +87,27 @@
tracer_(NULL),
use_compile_time_class_path_(false),
main_thread_group_(NULL),
- system_thread_group_(NULL) {
+ system_thread_group_(NULL)
+#if defined(ART_USE_LLVM_COMPILER)
+#if defined(__arm__)
+ , plt_(kArm)
+#elif defined(__mips__)
+ , plt_(kMips)
+#elif defined(__i386__)
+ , plt_(kX86)
+#endif
+#endif
+ {
for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
resolution_stub_array_[i] = NULL;
}
for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
callee_save_methods_[i] = NULL;
}
+
+#if defined(ART_USE_LLVM_COMPILER)
+ CHECK(plt_.AllocateTable()) << "Failed to allocate PLT";
+#endif
}
Runtime::~Runtime() {
diff --git a/src/runtime.h b/src/runtime.h
index a6cebe7..ba579ea 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -33,6 +33,10 @@
#include "safe_map.h"
#include "stringpiece.h"
+#if defined(ART_USE_LLVM_COMPILER)
+#include "compiler_llvm/procedure_linkage_table.h"
+#endif
+
namespace art {
template<class T> class PrimitiveArray;
@@ -422,6 +426,9 @@
jobject main_thread_group_;
jobject system_thread_group_;
+#if defined(ART_USE_LLVM_COMPILER)
+ compiler_llvm::ProcedureLinkageTable plt_;
+#endif
DISALLOW_COPY_AND_ASSIGN(Runtime);
};