Remove ExtractCodeAndPrelink and switch Portable to MCLinker
Change-Id: Ia2459c7da6b79e0a1c0f1148c6e28ad9cbbe27a2
diff --git a/src/compiler/dex/compiler_ir.h b/src/compiler/dex/compiler_ir.h
index 4ab98a6..f8cdd34 100644
--- a/src/compiler/dex/compiler_ir.h
+++ b/src/compiler/dex/compiler_ir.h
@@ -18,15 +18,18 @@
#define ART_SRC_COMPILER_DEX_COMPILER_IR_H_
#include <vector>
-#include "dex_instruction.h"
+
+#include <llvm/Module.h>
+
+#include "compiler/dex/quick/codegen.h"
#include "compiler/driver/compiler_driver.h"
#include "compiler/driver/dex_compilation_unit.h"
-#include "compiler_utility.h"
-#include "safe_map.h"
-#include "compiler/llvm/ir_builder.h"
#include "compiler/llvm/intrinsic_helper.h"
-#include "llvm/Module.h"
+#include "compiler/llvm/ir_builder.h"
#include "compiler_enums.h"
+#include "compiler_utility.h"
+#include "dex_instruction.h"
+#include "safe_map.h"
namespace art {
@@ -43,6 +46,9 @@
struct ArenaBitVector;
struct LIR;
class LLVMInfo;
+namespace llvm {
+class LlvmCompilationUnit;
+} // namespace llvm
struct PromotionMap {
RegLocationType core_location:3;
@@ -348,6 +354,7 @@
mstats(NULL),
checkstats(NULL),
gen_bitcode(false),
+ llvm_compilation_unit(NULL),
llvm_info(NULL),
context(NULL),
module(NULL),
@@ -507,7 +514,11 @@
Memstats* mstats;
Checkstats* checkstats;
bool gen_bitcode;
+
+ // Fields for Portable
+ llvm::LlvmCompilationUnit* llvm_compilation_unit;
LLVMInfo* llvm_info;
+ std::string symbol;
::llvm::LLVMContext* context;
::llvm::Module* module;
::llvm::Function* func;
@@ -516,6 +527,7 @@
::llvm::BasicBlock* placeholder_bb;
::llvm::BasicBlock* entry_bb;
::llvm::BasicBlock* entryTarget_bb;
+
std::string bitcode_filename;
GrowableList llvm_values;
int32_t temp_name;
diff --git a/src/compiler/dex/dataflow.cc b/src/compiler/dex/dataflow.cc
index ac3116e..f0f177a 100644
--- a/src/compiler/dex/dataflow.cc
+++ b/src/compiler/dex/dataflow.cc
@@ -2491,10 +2491,7 @@
LOG(WARNING) << "Unexpected invoke op: " << opcode;
return false;
}
- DexCompilationUnit m_unit(cu->class_loader, cu->class_linker,
- *cu->dex_file, cu->code_item,
- cu->class_def_idx, cu->method_idx,
- cu->access_flags);
+ DexCompilationUnit m_unit(cu);
// TODO: add a flag so we don't counts the stats for this twice
uint32_t dex_method_idx = mir->dalvikInsn.vB;
int vtable_idx;
diff --git a/src/compiler/dex/frontend.cc b/src/compiler/dex/frontend.cc
index 482804c..5b8faf4 100644
--- a/src/compiler/dex/frontend.cc
+++ b/src/compiler/dex/frontend.cc
@@ -14,8 +14,13 @@
* limitations under the License.
*/
+#include <llvm/Support/Threading.h>
+
#include "compiler/driver/compiler_driver.h"
#include "compiler_internals.h"
+#if defined(ART_USE_PORTABLE_COMPILER)
+#include "compiler/llvm/llvm_compilation_unit.h"
+#endif
#include "dataflow.h"
#include "ssa_transformation.h"
#include "leb128.h"
@@ -25,8 +30,6 @@
#include "portable/mir_to_gbc.h"
#include "quick/mir_to_lir.h"
-#include <llvm/Support/Threading.h>
-
namespace {
#if !defined(ART_USE_PORTABLE_COMPILER)
pthread_once_t llvm_multi_init = PTHREAD_ONCE_INIT;
@@ -782,8 +785,11 @@
const DexFile::CodeItem* code_item,
uint32_t access_flags, InvokeType invoke_type,
uint32_t class_def_idx, uint32_t method_idx,
- jobject class_loader, const DexFile& dex_file,
- LLVMInfo* llvm_info)
+ jobject class_loader, const DexFile& dex_file
+#if defined(ART_USE_PORTABLE_COMPILER)
+ , llvm::LlvmCompilationUnit* llvm_compilation_unit
+#endif
+)
{
VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "...";
@@ -818,7 +824,11 @@
if ((compiler_backend == kQuickGBC) || (compiler_backend == kPortable)) {
cu->gen_bitcode = true;
}
- cu->llvm_info = llvm_info;
+#if defined(ART_USE_PORTABLE_COMPILER)
+ cu->llvm_compilation_unit = llvm_compilation_unit;
+ cu->llvm_info = llvm_compilation_unit->GetQuickContext();
+ cu->symbol = llvm_compilation_unit->GetDexCompilationUnit()->GetSymbol();
+#endif
/* Adjust this value accordingly once inlining is performed */
cu->num_dalvik_registers = code_item->registers_size_;
// TODO: set this from command line
@@ -1137,6 +1147,7 @@
}
+#if defined(ART_USE_PORTABLE_COMPILER)
/* Go the LLVM path? */
if (cu->gen_bitcode) {
// MIR->Bitcode
@@ -1148,7 +1159,9 @@
}
// Bitcode->LIR
MethodBitcode2LIR(cu.get());
- } else {
+ } else
+#endif
+ {
if (special_case != kNoHandler) {
/*
* Custom codegen for special cases. If for any reason the
@@ -1231,13 +1244,20 @@
CompiledMethod* CompileOneMethod(CompilerDriver& compiler,
const CompilerBackend backend,
const DexFile::CodeItem* code_item,
- uint32_t access_flags, InvokeType invoke_type,
- uint32_t class_def_idx, uint32_t method_idx, jobject class_loader,
+ uint32_t access_flags,
+ InvokeType invoke_type,
+ uint32_t class_def_idx,
+ uint32_t method_idx,
+ jobject class_loader,
const DexFile& dex_file,
- LLVMInfo* llvm_info)
+ llvm::LlvmCompilationUnit* llvm_compilation_unit)
{
return CompileMethod(compiler, backend, code_item, access_flags, invoke_type, class_def_idx,
- method_idx, class_loader, dex_file, llvm_info);
+ method_idx, class_loader, dex_file
+#if defined(ART_USE_PORTABLE_COMPILER)
+ , llvm_compilation_unit
+#endif
+ );
}
} // namespace art
diff --git a/src/compiler/dex/portable/mir_to_gbc.cc b/src/compiler/dex/portable/mir_to_gbc.cc
index 8319b4d..e6900df 100644
--- a/src/compiler/dex/portable/mir_to_gbc.cc
+++ b/src/compiler/dex/portable/mir_to_gbc.cc
@@ -33,6 +33,8 @@
#include "compiler/dex/quick/codegen_util.h"
#include "compiler/dex/quick/local_optimizations.h"
#include "compiler/dex/quick/ralloc_util.h"
+#include "compiler/llvm/llvm_compilation_unit.h"
+#include "compiler/llvm/utils_llvm.h"
static const char* kLabelFormat = "%c0x%x_%d";
static const char kInvalidBlock = 0xff;
@@ -1982,17 +1984,14 @@
}
static bool CreateFunction(CompilationUnit* cu) {
- std::string func_name(PrettyMethod(cu->method_idx, *cu->dex_file,
- /* with_signature */ false));
::llvm::FunctionType* func_type = GetFunctionType(cu);
-
if (func_type == NULL) {
return false;
}
cu->func = ::llvm::Function::Create(func_type,
- ::llvm::Function::ExternalLinkage,
- func_name, cu->module);
+ ::llvm::Function::InternalLinkage,
+ cu->symbol, cu->module);
::llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
::llvm::Function::arg_iterator arg_end(cu->func->arg_end());
diff --git a/src/compiler/dex/quick/codegen.h b/src/compiler/dex/quick/codegen.h
index 63c8460..21290ca 100644
--- a/src/compiler/dex/quick/codegen.h
+++ b/src/compiler/dex/quick/codegen.h
@@ -17,6 +17,8 @@
#ifndef ART_SRC_COMPILER_DEX_QUICK_CODEGEN_H_
#define ART_SRC_COMPILER_DEX_QUICK_CODEGEN_H_
+#include "invoke_type.h"
+#include "compiler/dex/compiler_enums.h"
#include "compiler/dex/compiler_ir.h"
namespace art {
@@ -82,6 +84,14 @@
#define REG_USE12 (REG_USE1 | REG_USE2)
#define REG_USE23 (REG_USE2 | REG_USE3)
+struct BasicBlock;
+struct CallInfo;
+struct CompilationUnit;
+struct LIR;
+struct MIR;
+struct RegLocation;
+struct RegisterInfo;
+
typedef int (*NextCallInsn)(CompilationUnit*, CallInfo*, int, uint32_t dex_idx,
uint32_t method_idx, uintptr_t direct_code,
uintptr_t direct_method, InvokeType type);
diff --git a/src/compiler/dex/quick/codegen_util.cc b/src/compiler/dex/quick/codegen_util.cc
index 5f8f6ef..110146f 100644
--- a/src/compiler/dex/quick/codegen_util.cc
+++ b/src/compiler/dex/quick/codegen_util.cc
@@ -54,10 +54,7 @@
bool FastInstance(CompilationUnit* cu, uint32_t field_idx,
int& field_offset, bool& is_volatile, bool is_put)
{
- DexCompilationUnit m_unit(cu->class_loader, cu->class_linker,
- *cu->dex_file, cu->code_item,
- cu->class_def_idx, cu->method_idx,
- cu->access_flags);
+ DexCompilationUnit m_unit(cu);
return cu->compiler_driver->ComputeInstanceFieldInfo(field_idx, &m_unit,
field_offset, is_volatile, is_put);
}
diff --git a/src/compiler/dex/quick/gen_common.cc b/src/compiler/dex/quick/gen_common.cc
index f14d6cf..a289252 100644
--- a/src/compiler/dex/quick/gen_common.cc
+++ b/src/compiler/dex/quick/gen_common.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "codegen_util.h"
+#include "compiler/dex/quick/codegen_util.h"
#include "compiler/dex/compiler_ir.h"
#include "oat/runtime/oat_support_entrypoints.h"
#include "ralloc_util.h"
@@ -354,8 +354,7 @@
bool is_volatile;
bool is_referrers_class;
- DexCompilationUnit m_unit(cu->class_loader, cu->class_linker, *cu->dex_file, cu->code_item,
- cu->class_def_idx, cu->method_idx, cu->access_flags);
+ DexCompilationUnit m_unit(cu);
bool fast_path =
cu->compiler_driver->ComputeStaticFieldInfo(field_idx, &m_unit,
@@ -446,10 +445,7 @@
bool is_volatile;
bool is_referrers_class;
- DexCompilationUnit m_unit(cu->class_loader, cu->class_linker,
- *cu->dex_file, cu->code_item,
- cu->class_def_idx, cu->method_idx,
- cu->access_flags);
+ DexCompilationUnit m_unit(cu);
bool fast_path =
cu->compiler_driver->ComputeStaticFieldInfo(field_idx, &m_unit,
diff --git a/src/compiler/dex/quick/gen_invoke.cc b/src/compiler/dex/quick/gen_invoke.cc
index 2c01c19..1ae29be 100644
--- a/src/compiler/dex/quick/gen_invoke.cc
+++ b/src/compiler/dex/quick/gen_invoke.cc
@@ -16,6 +16,7 @@
#include "codegen_util.h"
#include "compiler/dex/compiler_ir.h"
+#include "invoke_type.h"
#include "oat/runtime/oat_support_entrypoints.h"
#include "ralloc_util.h"
#include "x86/codegen_x86.h"
@@ -1335,10 +1336,7 @@
// Explicit register usage
LockCallTemps(cu);
- DexCompilationUnit m_unit(cu->class_loader, cu->class_linker,
- *cu->dex_file, cu->code_item,
- cu->class_def_idx, cu->method_idx,
- cu->access_flags);
+ DexCompilationUnit m_unit(cu);
uint32_t dex_method_idx = info->index;
int vtable_idx;
diff --git a/src/compiler/dex/quick/gen_loadstore.cc b/src/compiler/dex/quick/gen_loadstore.cc
index b945e31..a7baea4 100644
--- a/src/compiler/dex/quick/gen_loadstore.cc
+++ b/src/compiler/dex/quick/gen_loadstore.cc
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-#include "codegen_util.h"
+#include "compiler/dex/quick/codegen_util.h"
#include "compiler/dex/compiler_ir.h"
+#include "invoke_type.h"
#include "ralloc_util.h"
namespace art {
diff --git a/src/compiler/dex/quick/ralloc_util.cc b/src/compiler/dex/quick/ralloc_util.cc
index a782264..5b7de2c 100644
--- a/src/compiler/dex/quick/ralloc_util.cc
+++ b/src/compiler/dex/quick/ralloc_util.cc
@@ -16,10 +16,10 @@
/* This file contains register alloction support. */
-#include "codegen_util.h"
#include "compiler/dex/compiler_ir.h"
#include "compiler/dex/compiler_utility.h"
#include "compiler/dex/dataflow.h"
+#include "compiler/dex/quick/codegen_util.h"
#include "ralloc_util.h"
namespace art {
diff --git a/src/compiler/dex/write_elf.cc b/src/compiler/dex/write_elf.cc
index a78d98e..7e3d512 100644
--- a/src/compiler/dex/write_elf.cc
+++ b/src/compiler/dex/write_elf.cc
@@ -19,12 +19,17 @@
namespace art {
class CompilerDriver;
+class DexFile;
} // namespace art
extern "C" bool WriteElf(art::CompilerDriver& driver,
+ const std::string* host_prefix,
+ bool is_host,
+ const std::vector<const art::DexFile*>& dex_files,
std::vector<uint8_t>& oat_contents,
- art::File* file) {
- return art::ElfWriter::Create(file, oat_contents, driver);
+ art::File* file)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return art::ElfWriter::Create(file, oat_contents, dex_files, host_prefix, is_host, driver);
}
extern "C" bool FixupElf(art::File* file, uintptr_t oat_data_begin) {
return art::ElfWriter::Fixup(file, oat_data_begin);
@@ -34,3 +39,6 @@
size_t& oat_data_offset) {
art::ElfWriter::GetOatElfInformation(file, oat_loaded_size, oat_data_offset);
}
+extern "C" bool StripElf(art::File* file) {
+ return art::ElfWriter::Strip(file);
+}
diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc
index a28ba18..8856a00 100644
--- a/src/compiler/driver/compiler_driver.cc
+++ b/src/compiler/driver/compiler_driver.cc
@@ -1678,7 +1678,7 @@
const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx), &shorty_len);
bool is_static = (access_flags & kAccStatic) != 0;
std::string key(MakeInvokeStubKey(is_static, shorty));
- const CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(key);
+ CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(key);
if (compiled_invoke_stub == NULL) {
compiled_invoke_stub = (*create_invoke_stub_)(*this, is_static, shorty, shorty_len);
CHECK(compiled_invoke_stub != NULL);
@@ -1686,7 +1686,7 @@
}
if ((compiler_backend_ == kPortable) && !is_static) {
- const CompiledInvokeStub* compiled_proxy_stub = FindProxyStub(shorty);
+ CompiledInvokeStub* compiled_proxy_stub = FindProxyStub(shorty);
if (compiled_proxy_stub == NULL) {
compiled_proxy_stub = (*create_proxy_stub_)(*this, shorty, shorty_len);
CHECK(compiled_proxy_stub != NULL);
@@ -1701,12 +1701,12 @@
}
}
-const CompiledInvokeStub* CompilerDriver::FindInvokeStub(bool is_static, const char* shorty) const {
+CompiledInvokeStub* CompilerDriver::FindInvokeStub(bool is_static, const char* shorty) const {
const std::string key(MakeInvokeStubKey(is_static, shorty));
return FindInvokeStub(key);
}
-const CompiledInvokeStub* CompilerDriver::FindInvokeStub(const std::string& key) const {
+CompiledInvokeStub* CompilerDriver::FindInvokeStub(const std::string& key) const {
MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_);
InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key);
if (it == compiled_invoke_stubs_.end()) {
@@ -1717,8 +1717,7 @@
}
}
-void CompilerDriver::InsertInvokeStub(const std::string& key,
- const CompiledInvokeStub* compiled_invoke_stub) {
+void CompilerDriver::InsertInvokeStub(const std::string& key, CompiledInvokeStub* compiled_invoke_stub) {
MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_);
InvokeStubTable::iterator it = compiled_invoke_stubs_.find(key);
if (it != compiled_invoke_stubs_.end()) {
@@ -1729,7 +1728,7 @@
}
}
-const CompiledInvokeStub* CompilerDriver::FindProxyStub(const char* shorty) const {
+CompiledInvokeStub* CompilerDriver::FindProxyStub(const char* shorty) const {
MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_);
ProxyStubTable::const_iterator it = compiled_proxy_stubs_.find(shorty);
if (it == compiled_proxy_stubs_.end()) {
@@ -1740,8 +1739,7 @@
}
}
-void CompilerDriver::InsertProxyStub(const char* shorty,
- const CompiledInvokeStub* compiled_proxy_stub) {
+void CompilerDriver::InsertProxyStub(const char* shorty, CompiledInvokeStub* compiled_proxy_stub) {
MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_);
InvokeStubTable::iterator it = compiled_proxy_stubs_.find(shorty);
if (it != compiled_proxy_stubs_.end()) {
@@ -1795,11 +1793,21 @@
return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0;
}
-bool CompilerDriver::WriteElf(std::vector<uint8_t>& oat_contents, File* file) {
- typedef bool (*WriteElfFn)(CompilerDriver&, std::vector<uint8_t>&, File*);
+bool CompilerDriver::WriteElf(const std::string* host_prefix,
+ bool is_host,
+ const std::vector<const DexFile*>& dex_files,
+ std::vector<uint8_t>& oat_contents,
+ File* file) {
+ typedef bool (*WriteElfFn)(CompilerDriver&,
+ const std::string* host_prefix,
+ bool is_host,
+ const std::vector<const DexFile*>& dex_files,
+ std::vector<uint8_t>&,
+ File*);
WriteElfFn WriteElf =
FindFunction<WriteElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "WriteElf");
- return WriteElf(*this, oat_contents, file);
+ Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
+ return WriteElf(*this, host_prefix, is_host, dex_files, oat_contents, file);
}
bool CompilerDriver::FixupElf(File* file, uintptr_t oat_data_begin) const {
@@ -1819,11 +1827,18 @@
GetOatElfInformation(file, oat_loaded_size, oat_data_offset);
}
+bool CompilerDriver::StripElf(File* file) const {
+ typedef bool (*StripElfFn)(File*);
+ StripElfFn StripElf =
+ FindFunction<StripElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "StripElf");
+ return StripElf(file);
+}
+
void CompilerDriver::InstructionSetToLLVMTarget(InstructionSet instruction_set,
std::string& target_triple,
std::string& target_cpu,
std::string& target_attr) {
- switch (instruction_set) {
+ switch (instruction_set) {
case kThumb2:
target_triple = "thumb-none-linux-gnueabi";
target_cpu = "cortex-a9";
diff --git a/src/compiler/driver/compiler_driver.h b/src/compiler/driver/compiler_driver.h
index 49bc473..7f67c21 100644
--- a/src/compiler/driver/compiler_driver.h
+++ b/src/compiler/driver/compiler_driver.h
@@ -123,11 +123,11 @@
CompiledMethod* GetCompiledMethod(MethodReference ref) const
LOCKS_EXCLUDED(compiled_methods_lock_);
- const CompiledInvokeStub* FindInvokeStub(bool is_static, const char* shorty) const;
- const CompiledInvokeStub* FindInvokeStub(const std::string& key) const
+ CompiledInvokeStub* FindInvokeStub(bool is_static, const char* shorty) const;
+ CompiledInvokeStub* FindInvokeStub(const std::string& key) const
LOCKS_EXCLUDED(compiled_invoke_stubs_lock_);
- const CompiledInvokeStub* FindProxyStub(const char* shorty) const;
+ CompiledInvokeStub* FindProxyStub(const char* shorty) const;
void AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file, size_t class_def_index);
bool RequiresConstructorBarrier(Thread* self, const DexFile* dex_file, size_t class_def_index);
@@ -186,10 +186,15 @@
void SetBitcodeFileName(std::string const& filename);
- // TODO: remove when libart links against LLVM (when separate compiler library is gone)
- bool WriteElf(std::vector<uint8_t>& oat_contents, File* file);
+ // TODO: remove these Elf wrappers when libart links against LLVM (when separate compiler library is gone)
+ bool WriteElf(const std::string* host_prefix,
+ bool is_host,
+ const std::vector<const DexFile*>& dex_files,
+ std::vector<uint8_t>& oat_contents,
+ File* file);
bool FixupElf(File* file, uintptr_t oat_data_begin) const;
void GetOatElfInformation(File* file, size_t& oat_loaded_size, size_t& oat_data_offset) const;
+ bool StripElf(File* file) const;
// TODO: move to a common home for llvm helpers once quick/portable are merged
static void InstructionSetToLLVMTarget(InstructionSet instruction_set,
@@ -316,10 +321,10 @@
static void CompileClass(const ParallelCompilationManager* context, size_t class_def_index)
LOCKS_EXCLUDED(Locks::mutator_lock_);
- void InsertInvokeStub(const std::string& key, const CompiledInvokeStub* compiled_invoke_stub)
+ void InsertInvokeStub(const std::string& key, CompiledInvokeStub* compiled_invoke_stub)
LOCKS_EXCLUDED(compiled_invoke_stubs_lock_);
- void InsertProxyStub(const char* shorty, const CompiledInvokeStub* compiled_proxy_stub);
+ void InsertProxyStub(const char* shorty, CompiledInvokeStub* compiled_proxy_stub);
std::vector<const PatchInformation*> code_to_patch_;
std::vector<const PatchInformation*> methods_to_patch_;
@@ -342,12 +347,12 @@
mutable Mutex compiled_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
MethodTable compiled_methods_ GUARDED_BY(compiled_methods_lock_);
- typedef SafeMap<std::string, const CompiledInvokeStub*> InvokeStubTable;
+ typedef SafeMap<std::string, CompiledInvokeStub*> InvokeStubTable;
// Invocation stubs created to allow invocation of the compiled methods.
mutable Mutex compiled_invoke_stubs_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
InvokeStubTable compiled_invoke_stubs_ GUARDED_BY(compiled_invoke_stubs_lock_);
- typedef SafeMap<std::string, const CompiledInvokeStub*> ProxyStubTable;
+ typedef SafeMap<std::string, CompiledInvokeStub*> ProxyStubTable;
// Proxy stubs created for proxy invocation delegation
mutable Mutex compiled_proxy_stubs_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
ProxyStubTable compiled_proxy_stubs_ GUARDED_BY(compiled_proxy_stubs_lock_);
diff --git a/src/compiler/driver/compiler_driver_test.cc b/src/compiler/driver/compiler_driver_test.cc
index 19ccb35..dee448d 100644
--- a/src/compiler/driver/compiler_driver_test.cc
+++ b/src/compiler/driver/compiler_driver_test.cc
@@ -132,6 +132,7 @@
}
TEST_F(CompilerDriverTest, AbstractMethodErrorStub) {
+ TEST_DISABLED_FOR_PORTABLE();
jobject class_loader;
{
ScopedObjectAccess soa(Thread::Current());
diff --git a/src/compiler/driver/dex_compilation_unit.cc b/src/compiler/driver/dex_compilation_unit.cc
new file mode 100644
index 0000000..67987fa
--- /dev/null
+++ b/src/compiler/driver/dex_compilation_unit.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 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 "dex_compilation_unit.h"
+
+#include "base/stringprintf.h"
+#include "compiler/dex/compiler_ir.h"
+#include "utils.h"
+
+namespace art {
+
+DexCompilationUnit::DexCompilationUnit(CompilationUnit* cu)
+ : cu_(cu),
+ class_loader_(cu->class_loader),
+ class_linker_(cu->class_linker),
+ dex_file_(cu->dex_file),
+ code_item_(cu->code_item),
+ class_def_idx_(cu->class_def_idx),
+ dex_method_idx_(cu->method_idx),
+ access_flags_(cu->access_flags),
+ symbol_(StringPrintf("dex_%s", MangleForJni(PrettyMethod(dex_method_idx_, *dex_file_)).c_str())) {
+}
+
+DexCompilationUnit:: DexCompilationUnit(CompilationUnit* cu,
+ jobject class_loader,
+ ClassLinker* class_linker,
+ const DexFile& dex_file,
+ const DexFile::CodeItem* code_item,
+ uint32_t class_def_idx,
+ uint32_t method_idx,
+ uint32_t access_flags)
+ : cu_(cu),
+ class_loader_(class_loader),
+ class_linker_(class_linker),
+ dex_file_(&dex_file),
+ code_item_(code_item),
+ class_def_idx_(class_def_idx),
+ dex_method_idx_(method_idx),
+ access_flags_(access_flags),
+ symbol_(StringPrintf("dex_%s", MangleForJni(PrettyMethod(dex_method_idx_, *dex_file_)).c_str())) {
+}
+
+} // namespace art
diff --git a/src/compiler/driver/dex_compilation_unit.h b/src/compiler/driver/dex_compilation_unit.h
index 6a0218d..0fc1123 100644
--- a/src/compiler/driver/dex_compilation_unit.h
+++ b/src/compiler/driver/dex_compilation_unit.h
@@ -17,26 +17,29 @@
#ifndef ART_SRC_COMPILER_DEX_DEX_COMPILATION_UNIT_H_
#define ART_SRC_COMPILER_DEX_DEX_COMPILATION_UNIT_H_
-#include "dex_file.h"
-
#include <stdint.h>
+#include "dex_file.h"
+#include "jni.h"
+
namespace art {
namespace mirror {
class ClassLoader;
class DexCache;
} // namespace mirror
class ClassLinker;
-class DexFile;
+class CompilationUnit;
class DexCompilationUnit {
public:
- DexCompilationUnit(jobject class_loader, ClassLinker* class_linker, const DexFile& dex_file,
- const DexFile::CodeItem* code_item, uint32_t class_def_idx,
- uint32_t method_idx, uint32_t access_flags)
- : class_loader_(class_loader), class_linker_(class_linker), dex_file_(&dex_file),
- code_item_(code_item), class_def_idx_(class_def_idx), dex_method_idx_(method_idx),
- access_flags_(access_flags) {
+ DexCompilationUnit(CompilationUnit* cu);
+
+ DexCompilationUnit(CompilationUnit* cu, jobject class_loader, ClassLinker* class_linker,
+ const DexFile& dex_file, const DexFile::CodeItem* code_item,
+ uint32_t class_def_idx, uint32_t method_idx, uint32_t access_flags);
+
+ CompilationUnit* GetCompilationUnit() const {
+ return cu_;
}
jobject GetClassLoader() const {
@@ -89,8 +92,15 @@
return ((access_flags_ & kAccSynchronized) != 0);
}
+ const std::string& GetSymbol() const {
+ return symbol_;
+ }
+
private:
+ CompilationUnit* cu_;
+
const jobject class_loader_;
+
ClassLinker* const class_linker_;
const DexFile* const dex_file_;
@@ -99,6 +109,8 @@
const uint32_t class_def_idx_;
const uint32_t dex_method_idx_;
const uint32_t access_flags_;
+
+ const std::string symbol_;
};
} // namespace art
diff --git a/src/compiler/invoke_stubs/portable/stub_compiler.cc b/src/compiler/invoke_stubs/portable/stub_compiler.cc
index 5c314e6..ec6dc30 100644
--- a/src/compiler/invoke_stubs/portable/stub_compiler.cc
+++ b/src/compiler/invoke_stubs/portable/stub_compiler.cc
@@ -52,7 +52,7 @@
size_t shorty_size = strlen(shorty);
// Function name
- std::string func_name(ElfFuncName(cunit_->GetIndex()));
+ std::string func_name(StringPrintf("invoke_stub_%s%s", shorty, is_static ? "_static" : ""));
// Get argument types
::llvm::Type* arg_types[] = {
@@ -69,8 +69,8 @@
// Create function
::llvm::Function* func =
- ::llvm::Function::Create(func_type, ::llvm::Function::ExternalLinkage,
- func_name, module_);
+ ::llvm::Function::Create(func_type, ::llvm::Function::InternalLinkage,
+ func_name, module_);
// Create basic block for the body of this function
@@ -185,7 +185,8 @@
cunit_->Materialize();
return new CompiledInvokeStub(cunit_->GetInstructionSet(),
- cunit_->GetCompiledCode());
+ cunit_->GetElfObject(),
+ func_name);
}
@@ -194,7 +195,7 @@
size_t shorty_size = strlen(shorty);
// Function name
- std::string func_name(ElfFuncName(cunit_->GetIndex()));
+ std::string func_name(StringPrintf("proxy_stub_%s", shorty));
// Accurate function type
::llvm::Type* accurate_ret_type = irb_.getJType(shorty[0]);
@@ -212,7 +213,7 @@
// Create function
::llvm::Function* func =
- ::llvm::Function::Create(accurate_func_type, ::llvm::Function::ExternalLinkage,
+ ::llvm::Function::Create(accurate_func_type, ::llvm::Function::InternalLinkage,
func_name, module_);
switch(shorty[0]) {
case 'Z':
@@ -271,7 +272,8 @@
cunit_->Materialize();
return new CompiledInvokeStub(cunit_->GetInstructionSet(),
- cunit_->GetCompiledCode());
+ cunit_->GetElfObject(),
+ func_name);
}
diff --git a/src/compiler/jni/jni_compiler_test.cc b/src/compiler/jni/jni_compiler_test.cc
index 4ed7898..5176752 100644
--- a/src/compiler/jni/jni_compiler_test.cc
+++ b/src/compiler/jni/jni_compiler_test.cc
@@ -130,6 +130,7 @@
}
TEST_F(JniCompilerTest, CompileAndRunNoArgMethod) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "foo", "()V",
reinterpret_cast<void*>(&Java_MyClassNatives_foo));
@@ -141,6 +142,7 @@
}
TEST_F(JniCompilerTest, CompileAndRunIntMethodThroughStub) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "bar", "(I)I",
NULL /* calling through stub will link with &Java_MyClassNatives_bar */);
@@ -155,6 +157,7 @@
}
TEST_F(JniCompilerTest, CompileAndRunStaticIntMethodThroughStub) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(true, "sbar", "(I)I",
NULL /* calling through stub will link with &Java_MyClassNatives_sbar */);
@@ -181,6 +184,7 @@
}
TEST_F(JniCompilerTest, CompileAndRunIntMethod) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "fooI", "(I)I",
reinterpret_cast<void*>(&Java_MyClassNatives_fooI));
@@ -206,6 +210,7 @@
}
TEST_F(JniCompilerTest, CompileAndRunIntIntMethod) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "fooII", "(II)I",
reinterpret_cast<void*>(&Java_MyClassNatives_fooII));
@@ -232,6 +237,7 @@
}
TEST_F(JniCompilerTest, CompileAndRunLongLongMethod) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "fooJJ", "(JJ)J",
reinterpret_cast<void*>(&Java_MyClassNatives_fooJJ));
@@ -259,6 +265,7 @@
}
TEST_F(JniCompilerTest, CompileAndRunDoubleDoubleMethod) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "fooDD", "(DD)D",
reinterpret_cast<void*>(&Java_MyClassNatives_fooDD));
@@ -287,6 +294,7 @@
}
TEST_F(JniCompilerTest, CompileAndRun_fooJJ_synchronized) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "fooJJ_synchronized", "(JJ)J",
reinterpret_cast<void*>(&Java_MyClassNatives_fooJJ_synchronized));
@@ -319,6 +327,7 @@
}
TEST_F(JniCompilerTest, CompileAndRunIntObjectObjectMethod) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "fooIOO",
"(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
reinterpret_cast<void*>(&Java_MyClassNatives_fooIOO));
@@ -362,6 +371,7 @@
}
TEST_F(JniCompilerTest, CompileAndRunStaticIntIntMethod) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(true, "fooSII", "(II)I",
reinterpret_cast<void*>(&Java_MyClassNatives_fooSII));
@@ -384,6 +394,7 @@
}
TEST_F(JniCompilerTest, CompileAndRunStaticDoubleDoubleMethod) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(true, "fooSDD", "(DD)D",
reinterpret_cast<void*>(&Java_MyClassNatives_fooSDD));
@@ -420,6 +431,7 @@
TEST_F(JniCompilerTest, CompileAndRunStaticIntObjectObjectMethod) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(true, "fooSIOO",
"(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
reinterpret_cast<void*>(&Java_MyClassNatives_fooSIOO));
@@ -470,6 +482,7 @@
}
TEST_F(JniCompilerTest, CompileAndRunStaticSynchronizedIntObjectObjectMethod) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(true, "fooSSIOO",
"(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
reinterpret_cast<void*>(&Java_MyClassNatives_fooSSIOO));
@@ -506,6 +519,7 @@
}
TEST_F(JniCompilerTest, ExceptionHandling) {
+ TEST_DISABLED_FOR_PORTABLE();
{
ASSERT_FALSE(runtime_->IsStarted());
ScopedObjectAccess soa(Thread::Current());
@@ -585,6 +599,7 @@
}
TEST_F(JniCompilerTest, NativeStackTraceElement) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "fooI", "(I)I",
reinterpret_cast<void*>(&Java_MyClassNatives_nativeUpCall));
jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 10);
@@ -596,6 +611,7 @@
}
TEST_F(JniCompilerTest, ReturnGlobalRef) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "fooO", "(Ljava/lang/Object;)Ljava/lang/Object;",
reinterpret_cast<void*>(&Java_MyClassNatives_fooO));
jobject result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, jobj_);
@@ -613,6 +629,7 @@
}
TEST_F(JniCompilerTest, LocalReferenceTableClearingTest) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "fooI", "(I)I", reinterpret_cast<void*>(&local_ref_test));
// 1000 invocations of a method that adds 10 local references
for (int i = 0; i < 1000; i++) {
@@ -631,6 +648,7 @@
}
TEST_F(JniCompilerTest, JavaLangSystemArrayCopy) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(true, "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V",
reinterpret_cast<void*>(&my_arraycopy));
env_->CallStaticVoidMethod(jklass_, jmethod_, jobj_, 1234, jklass_, 5678, 9876);
@@ -646,6 +664,7 @@
}
TEST_F(JniCompilerTest, CompareAndSwapInt) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "compareAndSwapInt", "(Ljava/lang/Object;JII)Z",
reinterpret_cast<void*>(&my_casi));
jboolean result = env_->CallBooleanMethod(jobj_, jmethod_, jobj_, 0x12345678ABCDEF88ll, 0xCAFEF00D, 0xEBADF00D);
@@ -662,6 +681,7 @@
}
TEST_F(JniCompilerTest, GetText) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(true, "getText", "(JLjava/lang/Object;JLjava/lang/Object;)I",
reinterpret_cast<void*>(&my_gettext));
jint result = env_->CallStaticIntMethod(jklass_, jmethod_, 0x12345678ABCDEF88ll, jobj_,
@@ -670,6 +690,7 @@
}
TEST_F(JniCompilerTest, GetSinkPropertiesNative) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "getSinkPropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;", NULL);
// This space intentionally left blank. Just testing compilation succeeds.
}
@@ -685,6 +706,7 @@
}
TEST_F(JniCompilerTest, UpcallReturnTypeChecking_Instance) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "instanceMethodThatShouldReturnClass", "()Ljava/lang/Class;",
reinterpret_cast<void*>(&Java_MyClassNatives_instanceMethodThatShouldReturnClass));
@@ -702,6 +724,7 @@
}
TEST_F(JniCompilerTest, UpcallReturnTypeChecking_Static) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(true, "staticMethodThatShouldReturnClass", "()Ljava/lang/Class;",
reinterpret_cast<void*>(&Java_MyClassNatives_staticMethodThatShouldReturnClass));
@@ -727,6 +750,7 @@
}
TEST_F(JniCompilerTest, UpcallArgumentTypeChecking_Instance) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(false, "instanceMethodThatShouldTakeClass", "(ILjava/lang/Class;)V",
reinterpret_cast<void*>(&Java_MyClassNatives_instanceMethodThatShouldTakeClass));
@@ -737,6 +761,7 @@
}
TEST_F(JniCompilerTest, UpcallArgumentTypeChecking_Static) {
+ TEST_DISABLED_FOR_PORTABLE();
SetUpForTest(true, "staticMethodThatShouldTakeClass", "(ILjava/lang/Class;)V",
reinterpret_cast<void*>(&Java_MyClassNatives_staticMethodThatShouldTakeClass));
diff --git a/src/compiler/jni/portable/jni_compiler.cc b/src/compiler/jni/portable/jni_compiler.cc
index 1a4ad95..8495150 100644
--- a/src/compiler/jni/portable/jni_compiler.cc
+++ b/src/compiler/jni/portable/jni_compiler.cc
@@ -64,7 +64,10 @@
char const return_shorty = dex_file->GetMethodShorty(method_id)[0];
::llvm::Value* this_object_or_class_object;
- CreateFunction();
+ uint32_t method_idx = dex_compilation_unit_->GetDexMethodIndex();
+ std::string func_name(StringPrintf("jni_%s",
+ MangleForJni(PrettyMethod(method_idx, *dex_file)).c_str()));
+ CreateFunction(func_name);
// Set argument name
::llvm::Function::arg_iterator arg_begin(func_->arg_begin());
@@ -233,13 +236,13 @@
cunit_->Materialize();
return new CompiledMethod(cunit_->GetInstructionSet(),
- cunit_->GetCompiledCode());
+ cunit_->GetElfObject(),
+ func_name);
}
-void JniCompiler::CreateFunction() {
- // LLVM function name
- std::string func_name(ElfFuncName(cunit_->GetIndex()));
+void JniCompiler::CreateFunction(const std::string& func_name) {
+ CHECK_NE(0U, func_name.size());
const bool is_static = dex_compilation_unit_->IsStatic();
@@ -248,8 +251,8 @@
GetFunctionType(dex_compilation_unit_->GetDexMethodIndex(), is_static, false);
// Create function
- func_ = ::llvm::Function::Create(func_type, ::llvm::Function::ExternalLinkage,
- func_name, module_);
+ func_ = ::llvm::Function::Create(func_type, ::llvm::Function::InternalLinkage,
+ func_name, module_);
// Create basic block
::llvm::BasicBlock* basic_block = ::llvm::BasicBlock::Create(*context_, "B0", func_);
diff --git a/src/compiler/jni/portable/jni_compiler.h b/src/compiler/jni/portable/jni_compiler.h
index 3df81a5..a04277c 100644
--- a/src/compiler/jni/portable/jni_compiler.h
+++ b/src/compiler/jni/portable/jni_compiler.h
@@ -19,6 +19,8 @@
#include <stdint.h>
+#include <string>
+
namespace art {
class ClassLinker;
class CompiledMethod;
@@ -58,10 +60,10 @@
CompiledMethod* Compile();
private:
- void CreateFunction();
+ void CreateFunction(const std::string& symbol);
::llvm::FunctionType* GetFunctionType(uint32_t method_idx,
- bool is_static, bool is_target_function);
+ bool is_static, bool is_target_function);
private:
LlvmCompilationUnit* cunit_;
diff --git a/src/compiler/llvm/compiler_llvm.cc b/src/compiler/llvm/compiler_llvm.cc
index 1c9a494..be1730f 100644
--- a/src/compiler/llvm/compiler_llvm.cc
+++ b/src/compiler/llvm/compiler_llvm.cc
@@ -16,14 +16,15 @@
#include "compiler_llvm.h"
-#include "base/stl_util.h"
#include "backend_options.h"
+#include "base/stl_util.h"
#include "class_linker.h"
#include "compiled_method.h"
#include "compiler/driver/compiler_driver.h"
#include "compiler/driver/dex_compilation_unit.h"
#include "compiler/invoke_stubs/portable/stub_compiler.h"
#include "compiler/jni/portable/jni_compiler.h"
+#include "globals.h"
#include "ir_builder.h"
#include "llvm_compilation_unit.h"
#include "oat_file.h"
@@ -43,7 +44,7 @@
uint32_t access_flags, InvokeType invoke_type,
uint32_t class_def_idx, uint32_t method_idx, jobject class_loader,
const DexFile& dex_file,
- LLVMInfo* llvm_info);
+ llvm::LlvmCompilationUnit* llvm_info);
}
namespace llvm {
@@ -65,17 +66,17 @@
art::llvm::InitialBackendOptions();
// Initialize LLVM target, MC subsystem, asm printer, and asm parser.
-#if defined(ART_TARGET)
- // Don't initialize all targets on device. Just initialize the device's native target
- llvm::InitializeNativeTarget();
- llvm::InitializeNativeTargetAsmPrinter();
- llvm::InitializeNativeTargetAsmParser();
-#else
- llvm::InitializeAllTargets();
- llvm::InitializeAllTargetMCs();
- llvm::InitializeAllAsmPrinters();
- llvm::InitializeAllAsmParsers();
-#endif
+ if (art::kIsTargetBuild) {
+ // Don't initialize all targets on device. Just initialize the device's native target
+ llvm::InitializeNativeTarget();
+ llvm::InitializeNativeTargetAsmPrinter();
+ llvm::InitializeNativeTargetAsmParser();
+ } else {
+ llvm::InitializeAllTargets();
+ llvm::InitializeAllTargetMCs();
+ llvm::InitializeAllAsmPrinters();
+ llvm::InitializeAllAsmParsers();
+ }
// Initialize LLVM optimization passes
llvm::PassRegistry ®istry = *llvm::PassRegistry::getPassRegistry();
@@ -110,8 +111,7 @@
CompilerLLVM::CompilerLLVM(CompilerDriver* driver, InstructionSet insn_set)
: compiler_driver_(driver), insn_set_(insn_set),
- num_cunits_lock_("compilation unit counter lock"), num_cunits_(0),
- plt_(insn_set) {
+ next_cunit_id_lock_("compilation unit id lock"), next_cunit_id_(1) {
// Initialize LLVM libraries
pthread_once(&llvm_initialized, InitializeLLVM);
@@ -123,10 +123,12 @@
LlvmCompilationUnit* CompilerLLVM::AllocateCompilationUnit() {
- MutexLock GUARD(Thread::Current(), num_cunits_lock_);
- LlvmCompilationUnit* cunit = new LlvmCompilationUnit(this, ++num_cunits_);
+ MutexLock GUARD(Thread::Current(), next_cunit_id_lock_);
+ LlvmCompilationUnit* cunit = new LlvmCompilationUnit(this, next_cunit_id_++);
if (!bitcode_filename_.empty()) {
- cunit->SetBitcodeFileName(StringPrintf("%s-%zu", bitcode_filename_.c_str(), cunit->GetIndex()));
+ cunit->SetBitcodeFileName(StringPrintf("%s-%zu",
+ bitcode_filename_.c_str(),
+ cunit->GetCompilationUnitId()));
}
return cunit;
}
@@ -136,8 +138,8 @@
CompileDexMethod(DexCompilationUnit* dex_compilation_unit, InvokeType invoke_type) {
UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());
- std::string methodName(PrettyMethod(dex_compilation_unit->GetDexMethodIndex(),
- *dex_compilation_unit->GetDexFile()));
+ cunit->SetDexCompilationUnit(dex_compilation_unit);
+ cunit->SetCompiler(compiler_driver_);
// TODO: consolidate ArtCompileMethods
CompileOneMethod(*compiler_driver_,
kPortable,
@@ -148,19 +150,16 @@
dex_compilation_unit->GetDexMethodIndex(),
dex_compilation_unit->GetClassLoader(),
*dex_compilation_unit->GetDexFile(),
- cunit->GetQuickContext()
- );
-
- cunit->SetCompiler(compiler_driver_);
- cunit->SetDexCompilationUnit(dex_compilation_unit);
+ cunit.get());
cunit->Materialize();
CompilerDriver::MethodReference mref(dex_compilation_unit->GetDexFile(),
dex_compilation_unit->GetDexMethodIndex());
return new CompiledMethod(compiler_driver_->GetInstructionSet(),
- cunit->GetCompiledCode(),
- *verifier::MethodVerifier::GetDexGcMap(mref));
+ cunit->GetElfObject(),
+ *verifier::MethodVerifier::GetDexGcMap(mref),
+ cunit->GetDexCompilationUnit()->GetSymbol());
}
@@ -235,7 +234,7 @@
art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
art::DexCompilationUnit dex_compilation_unit(
- class_loader, class_linker, dex_file, code_item,
+ NULL, class_loader, class_linker, dex_file, code_item,
class_def_idx, method_idx, access_flags);
art::llvm::CompilerLLVM* compiler_llvm = ContextOf(driver);
art::CompiledMethod* result = compiler_llvm->CompileDexMethod(&dex_compilation_unit, invoke_type);
@@ -248,7 +247,7 @@
art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
art::DexCompilationUnit dex_compilation_unit(
- NULL, class_linker, dex_file, NULL,
+ NULL, NULL, class_linker, dex_file, NULL,
0, method_idx, access_flags);
art::llvm::CompilerLLVM* compiler_llvm = ContextOf(driver);
diff --git a/src/compiler/llvm/compiler_llvm.h b/src/compiler/llvm/compiler_llvm.h
index 870a541..cbee115 100644
--- a/src/compiler/llvm/compiler_llvm.h
+++ b/src/compiler/llvm/compiler_llvm.h
@@ -22,7 +22,6 @@
#include "dex_file.h"
#include "instruction_set.h"
#include "mirror/object.h"
-#include "procedure_linkage_table.h"
#include <UniquePtr.h>
@@ -87,10 +86,6 @@
CompiledInvokeStub* CreateProxyStub(const char *shorty);
- const ProcedureLinkageTable& GetProcedureLinkageTable() const {
- return plt_;
- }
-
private:
LlvmCompilationUnit* AllocateCompilationUnit();
@@ -98,13 +93,11 @@
InstructionSet insn_set_;
- Mutex num_cunits_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
- size_t num_cunits_ GUARDED_BY(num_cunits_lock_);
+ Mutex next_cunit_id_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
+ size_t next_cunit_id_ GUARDED_BY(next_cunit_id_lock_);
std::string bitcode_filename_;
- ProcedureLinkageTable plt_;
-
DISALLOW_COPY_AND_ASSIGN(CompilerLLVM);
};
diff --git a/src/compiler/llvm/compiler_runtime_func_list.h b/src/compiler/llvm/compiler_runtime_func_list.h
deleted file mode 100644
index ffbae85..0000000
--- a/src/compiler/llvm/compiler_runtime_func_list.h
+++ /dev/null
@@ -1,234 +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_COMPILER_RUNTIME_FUNC_LIST_H_
-#define ART_SRC_COMPILER_LLVM_COMPILER_RUNTIME_FUNC_LIST_H_
-
-// NOTE: COMPILER_RUNTIME_FUNC_LIST_* should be sorted!
-
-#define COMPILER_RUNTIME_FUNC_LIST_X86(V) \
- V(__ashldi3, long long, long long, int) \
- V(__ashrdi3, long long, long long, int) \
- V(__divdi3, long long, long long, long long) \
- V(__fixdfdi, long long, double) \
- V(__fixsfdi, long long, float) \
- V(__fixtfdi, long long, long double) \
- V(__fixtfsi, int, long double) \
- V(__fixunsdfdi, unsigned long long, double) \
- V(__fixunsdfsi, unsigned int, double) \
- V(__fixunssfdi, unsigned long long, float) \
- V(__fixunssfsi, unsigned int, float) \
- V(__fixunstfdi, unsigned long long, long double) \
- V(__fixunstfsi, unsigned int, long double) \
- V(__fixunsxfdi, unsigned long long, long double) \
- V(__fixunsxfsi, unsigned int, long double) \
- V(__fixxfdi, long long, long double) \
- V(__floatdidf, double, long long) \
- V(__floatdisf, float, long long) \
- V(__floatditf, long double, long long) \
- V(__floatdixf, long double, long long) \
- V(__floatsitf, long double, int) \
- V(__floatundidf, double, unsigned long long) \
- V(__floatundisf, float, unsigned long long) \
- V(__floatunditf, long double, unsigned long long) \
- V(__floatundixf, long double, unsigned long long) \
- V(__floatunsitf, long double, int) \
- V(__lshrdi3, long long, long long, int) \
- V(__moddi3, long long, long long, long long) \
- V(__muldi3, long long, long long, long long) \
- V(__negdi2, long long, long long) \
- V(__powidf2, double, double, int) \
- V(__powisf2, float, float, int) \
- V(__powitf2, long double, long double, int) \
- V(__powixf2, long double, long double, int) \
- V(__trunctfdf2, double, long double) \
- V(__trunctfsf2, float, long double) \
- V(__udivdi3, unsigned long long, unsigned long long, unsigned long long) \
- V(__umoddi3, unsigned long long, unsigned long long, unsigned long long) \
- V(ceil, double, double) \
- V(ceilf, float, float) \
- V(ceill, long double, long double) \
- V(copysign, double, double, double) \
- V(copysignf, float, float, float) \
- V(copysignl, long double, long double, long double) \
- V(cos, double, double) \
- V(cosf, float, float) \
- V(exp, double, double) \
- V(exp2, double, double) \
- V(exp2f, float, float) \
- V(expf, float, float) \
- V(floor, double, double) \
- V(floorf, float, float) \
- V(floorl, long double, long double) \
- V(fma, double, double, double, double) \
- V(fmaf, float, float, float, float) \
- V(fmod, double, double, double) \
- V(fmodf, float, float, float) \
- V(log, double, double) \
- V(log10, double, double) \
- V(log10f, float, float) \
- V(logf, float, float) \
- V(memcpy, void *, void *, const void *, size_t) \
- V(memmove, void *, void *, const void *, size_t) \
- V(memset, void *, void *, int, size_t) \
- V(nearbyint, double, double) \
- V(nearbyintf, float, float) \
- V(pow, double, double, double) \
- V(powf, float, float, float) \
- V(rint, double, double) \
- V(rintf, float, float) \
- V(sin, double, double) \
- V(sinf, float, float) \
- V(sqrt, double, double) \
- V(sqrtf, float, float) \
- V(trunc, double, double) \
- V(truncf, float, float) \
- V(truncl, long double, long double)
-
-#define COMPILER_RUNTIME_FUNC_LIST_MIPS(V) \
- V(__ashldi3, long long, long long, int) \
- V(__ashrdi3, long long, long long, int) \
- V(__divdi3, long long, long long, long long) \
- V(__fixdfdi, long long, double) \
- V(__fixsfdi, long long, float) \
- V(__fixunsdfdi, unsigned long long, double) \
- V(__fixunsdfsi, unsigned int, double) \
- V(__fixunssfdi, unsigned long long, float) \
- V(__fixunssfsi, unsigned int, float) \
- V(__floatdidf, double, long long) \
- V(__floatdisf, float, long long) \
- V(__floatundidf, double, unsigned long long) \
- V(__floatundisf, float, unsigned long long) \
- V(__lshrdi3, long long, long long, int) \
- V(__moddi3, long long, long long, long long) \
- V(__muldi3, long long, long long, long long) \
- V(__negdi2, long long, long long) \
- V(__powidf2, double, double, int) \
- V(__powisf2, float, float, int) \
- V(__udivdi3, unsigned long long, unsigned long long, unsigned long long) \
- V(__umoddi3, unsigned long long, unsigned long long, unsigned long long) \
- V(ceil, double, double) \
- V(ceilf, float, float) \
- V(ceill, long double, long double) \
- V(copysign, double, double, double) \
- V(copysignf, float, float, float) \
- V(copysignl, long double, long double, long double) \
- V(cos, double, double) \
- V(cosf, float, float) \
- V(exp, double, double) \
- V(exp2, double, double) \
- V(exp2f, float, float) \
- V(expf, float, float) \
- V(floor, double, double) \
- V(floorf, float, float) \
- V(floorl, long double, long double) \
- V(fma, double, double, double, double) \
- V(fmaf, float, float, float, float) \
- V(fmod, double, double, double) \
- V(fmodf, float, float, float) \
- V(log, double, double) \
- V(log10, double, double) \
- V(log10f, float, float) \
- V(logf, float, float) \
- V(memcpy, void *, void *, const void *, size_t) \
- V(memmove, void *, void *, const void *, size_t) \
- V(memset, void *, void *, int, size_t) \
- V(nearbyint, double, double) \
- V(nearbyintf, float, float) \
- V(pow, double, double, double) \
- V(powf, float, float, float) \
- V(rint, double, double) \
- V(rintf, float, float) \
- V(sin, double, double) \
- V(sinf, float, float) \
- V(sqrt, double, double) \
- V(sqrtf, float, float) \
- V(trunc, double, double) \
- V(truncf, float, float) \
- V(truncl, long double, long double)
-
-#define COMPILER_RUNTIME_FUNC_LIST_ARM(V) \
- V(__aeabi_d2f, float, double) \
- V(__aeabi_d2iz, int, double) \
- V(__aeabi_d2lz, long long, double) \
- V(__aeabi_d2uiz, unsigned, double) \
- V(__aeabi_d2ulz, unsigned long long, double) \
- V(__aeabi_dadd, double, double, double) \
- V(__aeabi_dcmpeq, int, double, double) \
- V(__aeabi_dcmpge, int, double, double) \
- V(__aeabi_dcmpgt, int, double, double) \
- V(__aeabi_dcmple, int, double, double) \
- V(__aeabi_dcmplt, int, double, double) \
- V(__aeabi_dcmpun, int, double, double) \
- V(__aeabi_ddiv, double, double, double) \
- V(__aeabi_dmul, double, double, double) \
- V(__aeabi_dsub, double, double, double) \
- V(__aeabi_f2d, double, float) \
- V(__aeabi_f2iz, int, float) \
- V(__aeabi_f2lz, long long, float) \
- V(__aeabi_f2uiz, unsigned int, float) \
- V(__aeabi_f2ulz, unsigned long long, float) \
- V(__aeabi_fadd, float, float, float) \
- V(__aeabi_fcmpeq, int, float, float) \
- V(__aeabi_fcmpge, int, float, float) \
- V(__aeabi_fcmpgt, int, float, float) \
- V(__aeabi_fcmple, int, float, float) \
- V(__aeabi_fcmplt, int, float, float) \
- V(__aeabi_fcmpun, int, float, float) \
- V(__aeabi_fdiv, float, float, float) \
- V(__aeabi_fmul, float, float, float) \
- V(__aeabi_fsub, float, float, float) \
- V(__aeabi_i2d, double, int) \
- V(__aeabi_i2f, float, int) \
- V(__aeabi_idiv, int, int, int) \
- V(__aeabi_l2d, double, long long) \
- V(__aeabi_l2f, float, long long) \
- V(__aeabi_lasr, long long, long long, int) \
- V(__aeabi_ldivmod, /* value in regs */ void, long long, long long) \
- V(__aeabi_llsl, long long, long long, int) \
- V(__aeabi_llsr, long long, long long, int) \
- V(__aeabi_lmul, long long, long long, long long) \
- V(__aeabi_memcpy, void, void *, const void *, size_t) \
- V(__aeabi_memmove, void, void *, const void *, size_t) \
- V(__aeabi_memset, void, void *, size_t, int) /* different from stdlib */ \
- V(__aeabi_ui2d, double, unsigned int) \
- V(__aeabi_ui2f, float, unsigned int) \
- V(__aeabi_uidiv, unsigned int, unsigned int, unsigned int) \
- V(__aeabi_ul2d, double, unsigned long long) \
- V(__aeabi_ul2f, float, unsigned long long) \
- V(__aeabi_uldivmod, /* value in regs */ void, unsigned long long, unsigned long long) \
- V(__moddi3, long long, long long, long long) \
- V(__modsi3, int, int, int) \
- V(__umoddi3, unsigned long long, unsigned long long, unsigned long long) \
- V(__umodsi3, unsigned int, unsigned int, unsigned int) \
- V(fmod, double, double, double) \
- V(fmodf, float, float, float) \
- V(memcpy, void *, void *, const void *, size_t) \
- V(memmove, void *, void *, const void *, size_t) \
- V(memset, void *, void *, int, size_t)
-
-
-#if defined(__arm__)
-#define COMPILER_RUNTIME_FUNC_LIST_NATIVE(V) COMPILER_RUNTIME_FUNC_LIST_ARM(V)
-#elif defined(__mips__)
-#define COMPILER_RUNTIME_FUNC_LIST_NATIVE(V) COMPILER_RUNTIME_FUNC_LIST_MIPS(V)
-#elif defined(__i386__)
-#define COMPILER_RUNTIME_FUNC_LIST_NATIVE(V) COMPILER_RUNTIME_FUNC_LIST_X86(V)
-#else
-#error "Unknown target platform"
-#endif
-
-#endif // ART_SRC_COMPILER_LLVM_COMPILER_RUNTIME_FUNC_LIST_H_
diff --git a/src/compiler/llvm/gbc_expander.cc b/src/compiler/llvm/gbc_expander.cc
index 4e1a91d..9de2e41 100644
--- a/src/compiler/llvm/gbc_expander.cc
+++ b/src/compiler/llvm/gbc_expander.cc
@@ -326,7 +326,7 @@
static char ID;
GBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
- art::CompilerDriver* compiler, art::DexCompilationUnit* dex_compilation_unit)
+ art::CompilerDriver* compiler, const art::DexCompilationUnit* dex_compilation_unit)
: llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb),
context_(irb.getContext()), rtb_(irb.Runtime()),
shadow_frame_(NULL), old_shadow_frame_(NULL),
@@ -350,7 +350,7 @@
VLOG(compiler) << "GBC expansion on " << func.getName().str();
// Runtime support or stub
- if (func.getName().startswith("art_") || func.getName().startswith("Art")) {
+ if (dex_compilation_unit_ == NULL) {
return false;
}
@@ -3634,7 +3634,7 @@
::llvm::FunctionPass*
CreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
- CompilerDriver* driver, DexCompilationUnit* dex_compilation_unit) {
+ CompilerDriver* driver, const DexCompilationUnit* dex_compilation_unit) {
return new GBCExpanderPass(intrinsic_helper, irb, driver, dex_compilation_unit);
}
diff --git a/src/compiler/llvm/llvm_compilation_unit.cc b/src/compiler/llvm/llvm_compilation_unit.cc
index aad18fb..3783ae9 100644
--- a/src/compiler/llvm/llvm_compilation_unit.cc
+++ b/src/compiler/llvm/llvm_compilation_unit.cc
@@ -16,16 +16,11 @@
#include "llvm_compilation_unit.h"
-#include "base/logging.h"
-#include "compiled_method.h"
-#include "compiler_llvm.h"
-#include "instruction_set.h"
-#include "ir_builder.h"
-#include "os.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
-#include "runtime_support_builder_arm.h"
-#include "runtime_support_builder_thumb2.h"
-#include "runtime_support_builder_x86.h"
+#include <string>
#include <llvm/ADT/OwningPtr.h>
#include <llvm/ADT/StringSet.h>
@@ -71,24 +66,30 @@
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
#include <llvm/Transforms/Scalar.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <string>
+#include "base/logging.h"
+#include "base/unix_file/fd_file.h"
+#include "compiled_method.h"
+#include "compiler_llvm.h"
+#include "instruction_set.h"
+#include "ir_builder.h"
+#include "os.h"
+#include "runtime_support_builder_arm.h"
+#include "runtime_support_builder_thumb2.h"
+#include "runtime_support_builder_x86.h"
+#include "utils_llvm.h"
namespace art {
namespace llvm {
::llvm::FunctionPass*
CreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
- CompilerDriver* compiler, DexCompilationUnit* dex_compilation_unit);
+ CompilerDriver* compiler, const DexCompilationUnit* dex_compilation_unit);
::llvm::Module* makeLLVMModuleContents(::llvm::Module* module);
-LlvmCompilationUnit::LlvmCompilationUnit(const CompilerLLVM* compiler_llvm, size_t cunit_idx)
- : compiler_llvm_(compiler_llvm), cunit_idx_(cunit_idx) {
+LlvmCompilationUnit::LlvmCompilationUnit(const CompilerLLVM* compiler_llvm, size_t cunit_id)
+ : compiler_llvm_(compiler_llvm), cunit_id_(cunit_id) {
driver_ = NULL;
dex_compilation_unit_ = NULL;
llvm_info_.reset(new LLVMInfo());
@@ -136,27 +137,24 @@
bool LlvmCompilationUnit::Materialize() {
- std::string elf_image;
-
// Compile and prelink ::llvm::Module
- if (!MaterializeToString(elf_image)) {
- LOG(ERROR) << "Failed to materialize compilation unit " << cunit_idx_;
+ if (!MaterializeToString(elf_object_)) {
+ LOG(ERROR) << "Failed to materialize compilation unit " << cunit_id_;
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_;
- return false;
+ if (false) {
+ // Dump the ELF image for debugging
+ std::string directory;
+ if (kIsTargetBuild) {
+ directory += GetArtCacheOrDie(GetAndroidData());
+ } else {
+ directory += "/tmp";
+ }
+ std::string filename(StringPrintf("%s/Art%u.o", directory.c_str(), cunit_id_));
+ UniquePtr<File> output(OS::OpenFile(filename.c_str(), true));
+ output->WriteFully(elf_object_.data(), elf_object_.size());
+ LOG(INFO) << ".o file written successfully: " << filename;
}
return true;
@@ -284,112 +282,6 @@
return true;
}
-bool LlvmCompilationUnit::ExtractCodeAndPrelink(const std::string& elf_image) {
- if (GetInstructionSet() == kX86) {
- compiled_code_.push_back(0xccU);
- compiled_code_.push_back(0xccU);
- compiled_code_.push_back(0xccU);
- compiled_code_.push_back(0xccU);
- return true;
- }
-
- ::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
diff --git a/src/compiler/llvm/llvm_compilation_unit.h b/src/compiler/llvm/llvm_compilation_unit.h
index 9ca9e3f..96d019c 100644
--- a/src/compiler/llvm/llvm_compilation_unit.h
+++ b/src/compiler/llvm/llvm_compilation_unit.h
@@ -53,8 +53,8 @@
public:
~LlvmCompilationUnit();
- size_t GetIndex() const {
- return cunit_idx_;
+ uint32_t GetCompilationUnitId() const {
+ return cunit_id_;
}
InstructionSet GetInstructionSet() const;
@@ -81,27 +81,30 @@
void SetCompiler(CompilerDriver* driver) {
driver_ = driver;
}
- void SetDexCompilationUnit(DexCompilationUnit* dex_compilation_unit) {
+ const DexCompilationUnit* GetDexCompilationUnit() {
+ return dex_compilation_unit_;
+ }
+ void SetDexCompilationUnit(const DexCompilationUnit* dex_compilation_unit) {
dex_compilation_unit_ = dex_compilation_unit;
}
bool Materialize();
bool IsMaterialized() const {
- return !compiled_code_.empty();
+ return !elf_object_.empty();
}
- const std::vector<uint8_t>& GetCompiledCode() const {
+ const std::string& GetElfObject() const {
DCHECK(IsMaterialized());
- return compiled_code_;
+ return elf_object_;
}
private:
LlvmCompilationUnit(const CompilerLLVM* compiler_llvm,
- size_t cunit_idx);
+ uint32_t cunit_id);
const CompilerLLVM* compiler_llvm_;
- const size_t cunit_idx_;
+ const uint32_t cunit_id_;
UniquePtr< ::llvm::LLVMContext> context_;
UniquePtr<IRBuilder> irb_;
@@ -110,11 +113,11 @@
UniquePtr<IntrinsicHelper> intrinsic_helper_;
UniquePtr<LLVMInfo> llvm_info_;
CompilerDriver* driver_;
- DexCompilationUnit* dex_compilation_unit_;
+ const DexCompilationUnit* dex_compilation_unit_;
std::string bitcode_filename_;
- std::vector<uint8_t> compiled_code_;
+ std::string elf_object_;
SafeMap<const ::llvm::Function*, CompiledMethod*> compiled_methods_map_;
@@ -123,8 +126,6 @@
bool MaterializeToString(std::string& str_buffer);
bool MaterializeToRawOStream(::llvm::raw_ostream& out_stream);
- bool ExtractCodeAndPrelink(const std::string& elf_image);
-
friend class CompilerLLVM; // For LlvmCompilationUnit constructor
};
diff --git a/src/compiler/llvm/procedure_linkage_table.cc b/src/compiler/llvm/procedure_linkage_table.cc
deleted file mode 100644
index 47ba9bd..0000000
--- a/src/compiler/llvm/procedure_linkage_table.cc
+++ /dev/null
@@ -1,326 +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 "procedure_linkage_table.h"
-
-#include "base/logging.h"
-#include "compiler_runtime_func_list.h"
-#include "globals.h"
-#include "instruction_set.h"
-#include "runtime_support_func_list.h"
-#include "runtime_support_llvm.h"
-#include "utils_llvm.h"
-
-#include <algorithm>
-
-#include <UniquePtr.h>
-
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-
-namespace {
- const char* const art_runtime_func_name_list[] = {
-#define DEFINE_ENTRY(ID, NAME) #NAME,
- RUNTIME_SUPPORT_FUNC_LIST(DEFINE_ENTRY)
-#undef DEFINE_ENTRY
- };
-
- const char* const compiler_runtime_func_name_list_arm[] = {
-#define DEFINE_ENTRY(NAME, RETURN_TYPE, ...) #NAME,
- COMPILER_RUNTIME_FUNC_LIST_ARM(DEFINE_ENTRY)
-#undef DEFINE_ENTRY
- };
-
- const char* const compiler_runtime_func_name_list_mips[] = {
-#define DEFINE_ENTRY(NAME, RETURN_TYPE, ...) #NAME,
- COMPILER_RUNTIME_FUNC_LIST_MIPS(DEFINE_ENTRY)
-#undef DEFINE_ENTRY
- };
-
- const char* const compiler_runtime_func_name_list_x86[] = {
-#define DEFINE_ENTRY(NAME, RETURN_TYPE, ...) #NAME,
- COMPILER_RUNTIME_FUNC_LIST_X86(DEFINE_ENTRY)
-#undef DEFINE_ENTRY
- };
-
- const size_t art_runtime_func_count =
- sizeof(art_runtime_func_name_list) / sizeof(const char*);
-
- const size_t compiler_runtime_func_count_arm =
- sizeof(compiler_runtime_func_name_list_arm) / sizeof(const char*);
-
- const size_t compiler_runtime_func_count_mips =
- sizeof(compiler_runtime_func_name_list_mips) / sizeof(const char*);
-
- const size_t compiler_runtime_func_count_x86 =
- sizeof(compiler_runtime_func_name_list_x86) / sizeof(const char*);
-}
-
-
-namespace art {
-namespace llvm {
-
-
-ProcedureLinkageTable::ProcedureLinkageTable(InstructionSet insn_set)
- : insn_set_(insn_set) {
-}
-
-
-ProcedureLinkageTable::~ProcedureLinkageTable() {
-}
-
-
-bool ProcedureLinkageTable::AllocateTable() {
- if (table_mmap_.get()) {
- return true;
- }
-
- // Allocate the PLT
- byte* suggested_table_addr = reinterpret_cast<byte*>(kTableAddress);
-
- UniquePtr<MemMap> table_mmap(
- MemMap::MapAnonymous(".plt", suggested_table_addr,
- GetTableSizeInBytes(), PROT_READ | PROT_WRITE));
-
- if (!table_mmap.get()) {
- return false;
- }
-
- if (table_mmap->Begin() != suggested_table_addr) {
- // Our PLT should be allocated at the FIXED address
- return false;
- }
-
- // Create the stubs in the PLT
- byte* stub_ptr = table_mmap->Begin();
- size_t stub_size = GetStubSizeInBytes();
-
- for (size_t i = 0; i < art_runtime_func_count; ++i, stub_ptr += stub_size) {
- const char* name = art_runtime_func_name_list[i];
- void* func = art_portable_find_runtime_support_func(NULL, name);
- DCHECK(func != NULL);
- CreateStub(stub_ptr, func);
- }
-
- const char* const* crt_name_list = NULL;
- size_t crt_count = 0u;
-
- switch (insn_set_) {
- case kArm:
- case kThumb2:
- crt_name_list = compiler_runtime_func_name_list_arm;
- crt_count = compiler_runtime_func_count_arm;
- break;
-
- case kMips:
- crt_name_list = compiler_runtime_func_name_list_mips;
- crt_count = compiler_runtime_func_count_mips;
- break;
-
- case kX86:
- crt_name_list = compiler_runtime_func_name_list_x86;
- crt_count = compiler_runtime_func_count_x86;
- break;
-
- default:
- LOG(FATAL) << "Unknown instruction set: " << insn_set_;
- return false;
- }
-
- for (size_t i = 0; i < crt_count; ++i, stub_ptr += stub_size) {
- void* func = art_portable_find_runtime_support_func(NULL, crt_name_list[i]);
- DCHECK(func != NULL);
- CreateStub(stub_ptr, func);
- }
-
- // Protect the procedure linkage table
- table_mmap->Protect(PROT_READ | PROT_EXEC);
-
- // Flush the instruction cache on specific architecture
-#if defined(__arm__) || defined(__mips__)
- cacheflush(reinterpret_cast<long int>(table_mmap->Begin()),
- reinterpret_cast<long int>(table_mmap->End()), 0);
-#endif
-
- // Transfer the ownership
- table_mmap_.reset(table_mmap.release());
-
- return true;
-}
-
-
-uintptr_t ProcedureLinkageTable::GetEntryAddress(const char* name) const {
- int func_idx = IndexOfRuntimeFunc(name);
- if (func_idx == -1) {
- return 0u;
- }
-
- return (kTableAddress + func_idx * GetStubSizeInBytes());
-}
-
-
-
-int ProcedureLinkageTable::IndexOfRuntimeFunc(const char* name) const {
- int result = IndexOfCompilerRuntimeFunc(name);
- if (result != -1) {
- return art_runtime_func_count + result;
- }
-
- return IndexOfArtRuntimeFunc(name);
-}
-
-
-int ProcedureLinkageTable::IndexOfArtRuntimeFunc(const char* name) {
- for (size_t i = 0; i < art_runtime_func_count; ++i) {
- if (strcmp(name, art_runtime_func_name_list[i]) == 0) {
- return static_cast<int>(i);
- }
- }
- return -1;
-}
-
-int ProcedureLinkageTable::IndexOfCompilerRuntimeFunc(InstructionSet insn_set,
- const char* name) {
- const char* const* rt_begin = NULL;
- const char* const* rt_end = NULL;
-
- switch (insn_set) {
- case kArm:
- case kThumb2:
- rt_begin = compiler_runtime_func_name_list_arm;
- rt_end = compiler_runtime_func_name_list_arm +
- compiler_runtime_func_count_arm;
- break;
-
- case kMips:
- rt_begin = compiler_runtime_func_name_list_mips;
- rt_end = compiler_runtime_func_name_list_mips +
- compiler_runtime_func_count_mips;
- break;
-
- case kX86:
- rt_begin = compiler_runtime_func_name_list_x86;
- rt_end = compiler_runtime_func_name_list_x86 +
- compiler_runtime_func_count_x86;
- break;
-
- default:
- LOG(FATAL) << "Unknown instruction set: " << insn_set;
- return -1;
- }
-
- const char* const* name_lbound_ptr =
- std::lower_bound(rt_begin, rt_end, name, CStringLessThanComparator());
-
- if (name_lbound_ptr < rt_end && strcmp(*name_lbound_ptr, name) == 0) {
- return (name_lbound_ptr - rt_begin);
- } else {
- return -1;
- }
-}
-
-
-size_t ProcedureLinkageTable::GetStubCount(InstructionSet insn_set) {
- switch (insn_set) {
- case kArm:
- case kThumb2:
- return art_runtime_func_count + compiler_runtime_func_count_arm;
-
- case kMips:
- return art_runtime_func_count + compiler_runtime_func_count_mips;
-
- case kX86:
- return art_runtime_func_count + compiler_runtime_func_count_x86;
-
- default:
- LOG(FATAL) << "Unknown instruction set: " << insn_set;
- return 0u;
- }
-}
-
-
-size_t ProcedureLinkageTable::GetStubSizeInBytes(InstructionSet insn_set) {
- switch (insn_set) {
- case kArm:
- case kThumb2:
- return 8u;
-
- case kMips:
- return 16u;
-
- case kX86:
- return 8u;
-
- default:
- LOG(FATAL) << "Unknown instruction set: " << insn_set;
- return 0u;
- }
-}
-
-
-void ProcedureLinkageTable::CreateStub(InstructionSet insn_set,
- byte* stub, void* dest_) {
- switch (insn_set) {
- case kArm:
- case kThumb2:
- {
- uint32_t dest = static_cast<uint32_t>(
- reinterpret_cast<uintptr_t>(dest_) & 0xfffffffful);
- uint32_t* stub_w = reinterpret_cast<uint32_t*>(stub);
-
- stub_w[0] = 0xe51ff004ul; // ldr pc, [pc #-4]
- stub_w[1] = dest;
- }
- break;
-
- case kMips:
- {
- uint32_t dest = static_cast<uint32_t>(
- reinterpret_cast<uintptr_t>(dest_) & 0xfffffffful);
- uint32_t* stub_w = reinterpret_cast<uint32_t*>(stub);
-
- stub_w[0] = 0x3c190000ul | ((dest >> 16) & 0xfffful); // lui
- stub_w[1] = 0x37390000ul | (dest & 0xfffful);; // ori
- stub_w[2] = 0x03200008ul; // jr (jump register)
- stub_w[3] = 0x00000000ul; // nop
- }
- break;
-
- case kX86:
- {
- uint32_t off = static_cast<uint32_t>(
- reinterpret_cast<uintptr_t>(dest_) -
- reinterpret_cast<uintptr_t>(stub + 1) - 4);
- // jmp (32-bit offset)
- stub[0] = 0xe9u;
- stub[1] = off & 0xffu;
- stub[2] = (off >> 8) & 0xffu;
- stub[2] = (off >> 16) & 0xffu;
- stub[2] = (off >> 24) & 0xffu;
- }
- break;
-
- default:
- LOG(FATAL) << "Unknown instruction set: " << insn_set;
- }
-}
-
-
-} // namespace llvm
-} // namespace art
diff --git a/src/compiler/llvm/procedure_linkage_table.h b/src/compiler/llvm/procedure_linkage_table.h
deleted file mode 100644
index 1c89d29..0000000
--- a/src/compiler/llvm/procedure_linkage_table.h
+++ /dev/null
@@ -1,85 +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_PROCEDURE_LINKAGE_TABLE_H_
-#define ART_SRC_COMPILER_LLVM_PROCEDURE_LINKAGE_TABLE_H_
-
-#include "globals.h"
-#include "instruction_set.h"
-#include "mem_map.h"
-
-#include <UniquePtr.h>
-
-#include <stddef.h>
-#include <stdint.h>
-
-namespace art {
-namespace llvm {
-
-
-class ProcedureLinkageTable {
- public:
- ProcedureLinkageTable(InstructionSet insn_set);
-
- ~ProcedureLinkageTable();
-
- bool AllocateTable();
-
- uintptr_t GetEntryAddress(const char* func_name) const;
-
- private:
- static size_t GetStubCount(InstructionSet insn_set);
- static size_t GetStubSizeInBytes(InstructionSet insn_set);
- static void CreateStub(InstructionSet insn_set,
- byte* stub, void* branch_dest);
-
- int IndexOfRuntimeFunc(const char* name) const;
- static int IndexOfArtRuntimeFunc(const char* name);
- static int IndexOfCompilerRuntimeFunc(InstructionSet insn_set,
- const char* name);
-
- size_t GetStubCount() const {
- return GetStubCount(insn_set_);
- }
-
- size_t GetStubSizeInBytes() const {
- return GetStubSizeInBytes(insn_set_);
- }
-
- size_t GetTableSizeInBytes() const {
- return GetStubSizeInBytes() * GetStubCount();
- }
-
- void CreateStub(byte* stub, void* branch_dest) {
- return CreateStub(insn_set_, stub, branch_dest);
- }
-
- int IndexOfCompilerRuntimeFunc(const char* name) const {
- return IndexOfCompilerRuntimeFunc(insn_set_, name);
- }
-
- InstructionSet insn_set_;
- UniquePtr<MemMap> table_mmap_;
-
- static const size_t kTableSizeInBytes = 1024u;
- static const uintptr_t kTableAddress = 0x5fffc000u;
-};
-
-
-} // namespace llvm
-} // namespace art
-
-#endif // ART_SRC_COMPILER_LLVM_PROCEDURE_LINKAGE_TABLE_H_
diff --git a/src/compiler/llvm/runtime_support_llvm.cc b/src/compiler/llvm/runtime_support_llvm.cc
index ae8bb4a..b18eefe 100644
--- a/src/compiler/llvm/runtime_support_llvm.cc
+++ b/src/compiler/llvm/runtime_support_llvm.cc
@@ -20,7 +20,6 @@
#include "asm_support.h"
#include "class_linker.h"
#include "class_linker-inl.h"
-#include "compiler_runtime_func_list.h"
#include "dex_file.h"
#include "dex_instruction.h"
#include "mirror/abstract_method-inl.h"
@@ -743,46 +742,6 @@
return o;
}
-//----------------------------------------------------------------------------
-// Runtime Support Function Lookup Callback
-//----------------------------------------------------------------------------
-
-#define EXTERNAL_LINKAGE(NAME, RETURN_TYPE, ...) \
-extern "C" RETURN_TYPE NAME(__VA_ARGS__);
-COMPILER_RUNTIME_FUNC_LIST_NATIVE(EXTERNAL_LINKAGE)
-#undef EXTERNAL_LINKAGE
-
-static void* art_portable_find_compiler_runtime_func(const char* name) {
-// TODO: If target support some math func, use the target's version. (e.g. art_portable_d2i -> __aeabi_d2iz)
- static const char* const names[] = {
-#define DEFINE_ENTRY(NAME, RETURN_TYPE, ...) #NAME ,
- COMPILER_RUNTIME_FUNC_LIST_NATIVE(DEFINE_ENTRY)
-#undef DEFINE_ENTRY
- };
-
- static void* const funcs[] = {
-#define DEFINE_ENTRY(NAME, RETURN_TYPE, ...) \
- reinterpret_cast<void*>(static_cast<RETURN_TYPE (*)(__VA_ARGS__)>(NAME)) ,
- COMPILER_RUNTIME_FUNC_LIST_NATIVE(DEFINE_ENTRY)
-#undef DEFINE_ENTRY
- };
-
- static const size_t num_entries = sizeof(names) / sizeof(const char* const);
-
- const char* const* const names_begin = names;
- const char* const* const names_end = names + num_entries;
-
- const char* const* name_lbound_ptr =
- std::lower_bound(names_begin, names_end, name,
- CStringLessThanComparator());
-
- if (name_lbound_ptr < names_end && strcmp(*name_lbound_ptr, name) == 0) {
- return funcs[name_lbound_ptr - names_begin];
- } else {
- return NULL;
- }
-}
-
// Handler for invocation on proxy methods. Create a boxed argument array and invoke the invocation
// handler which is a field within the proxy object receiver. The var args encode the arguments
// with the last argument being a pointer to a JValue to store the result in.
@@ -860,43 +819,6 @@
}
}
-void* art_portable_find_runtime_support_func(void* context, const char* name) {
- struct func_entry_t {
- const char* name;
- size_t name_len;
- void* addr;
- };
-
- static struct func_entry_t const tab[] = {
-#define DEFINE_ENTRY(ID, NAME) \
- { #NAME, sizeof(#NAME) - 1, reinterpret_cast<void*>(NAME) },
- RUNTIME_SUPPORT_FUNC_LIST(DEFINE_ENTRY)
-#undef DEFINE_ENTRY
- };
-
- static size_t const tab_size = sizeof(tab) / sizeof(struct func_entry_t);
-
- // Search the compiler runtime (such as __divdi3)
- void* result = art_portable_find_compiler_runtime_func(name);
- if (result != NULL) {
- return result;
- }
-
- // Note: Since our table is small, we are using trivial O(n) searching
- // function. For bigger table, it will be better to use a binary
- // search or hash function.
- size_t i;
- size_t name_len = strlen(name);
- for (i = 0; i < tab_size; ++i) {
- if (name_len == tab[i].name_len && strcmp(name, tab[i].name) == 0) {
- return tab[i].addr;
- }
- }
-
- LOG(FATAL) << "Error: Can't find symbol " << name;
- return 0;
-}
-
//----------------------------------------------------------------------------
// Memory barrier
//----------------------------------------------------------------------------
diff --git a/src/compiler/llvm/utils_llvm.h b/src/compiler/llvm/utils_llvm.h
index e06e113..2e273f4 100644
--- a/src/compiler/llvm/utils_llvm.h
+++ b/src/compiler/llvm/utils_llvm.h
@@ -17,13 +17,8 @@
#ifndef ART_SRC_UTILS_LLVM_H_
#define ART_SRC_UTILS_LLVM_H_
-#include "base/stringprintf.h"
-
#include <llvm/Analysis/Verifier.h>
-#include <stdint.h>
-#include <string>
-
namespace art {
#ifndef NDEBUG
@@ -32,17 +27,6 @@
#define VERIFY_LLVM_FUNCTION(func)
#endif
-inline static std::string ElfFuncName(uint32_t idx) {
- return StringPrintf("Art%u", static_cast<unsigned int>(idx));
-}
-
-class CStringLessThanComparator {
- public:
- bool operator()(const char* lhs, const char* rhs) const {
- return (strcmp(lhs, rhs) < 0);
- }
-};
-
} // namespace art
#endif // ART_SRC_UTILS_LLVM_H_