diff options
| -rw-r--r-- | build/Android.libart-compiler-llvm.mk | 4 | ||||
| -rw-r--r-- | src/class_linker.cc | 6 | ||||
| -rw-r--r-- | src/common_test.h | 1 | ||||
| -rw-r--r-- | src/compiled_method.cc | 4 | ||||
| -rw-r--r-- | src/compiled_method.h | 25 | ||||
| -rw-r--r-- | src/compiler_llvm/compiler_llvm.cc | 17 | ||||
| -rw-r--r-- | src/compiler_llvm/method_compiler.cc | 49 | ||||
| -rw-r--r-- | src/compiler_llvm/method_compiler.h | 1 | ||||
| -rw-r--r-- | src/compiler_llvm/runtime_support_llvm.cc | 2 | ||||
| -rw-r--r-- | src/compiler_llvm/runtime_support_llvm.h | 10 | ||||
| -rw-r--r-- | src/compiler_llvm/stub_compiler.cc (renamed from src/compiler_llvm/upcall_compiler.cc) | 89 | ||||
| -rw-r--r-- | src/compiler_llvm/stub_compiler.h (renamed from src/compiler_llvm/upcall_compiler.h) | 15 | ||||
| -rw-r--r-- | src/oat.cc | 6 | ||||
| -rw-r--r-- | src/oat.h | 4 | ||||
| -rw-r--r-- | src/oat_file.cc | 24 | ||||
| -rw-r--r-- | src/oat_file.h | 8 | ||||
| -rw-r--r-- | src/oat_writer.cc | 12 | ||||
| -rw-r--r-- | src/object.h | 16 |
18 files changed, 201 insertions, 92 deletions
diff --git a/build/Android.libart-compiler-llvm.mk b/build/Android.libart-compiler-llvm.mk index 3cbff80969..f27e83ef8f 100644 --- a/build/Android.libart-compiler-llvm.mk +++ b/build/Android.libart-compiler-llvm.mk @@ -30,8 +30,8 @@ LIBART_COMPILER_LLVM_SRC_FILES += \ src/compiler_llvm/runtime_support_builder_arm.cc \ src/compiler_llvm/runtime_support_builder_x86.cc \ src/compiler_llvm/runtime_support_llvm.cc \ - src/compiler_llvm/tbaa_info.cc \ - src/compiler_llvm/upcall_compiler.cc + src/compiler_llvm/stub_compiler.cc \ + src/compiler_llvm/tbaa_info.cc # $(1): target or host # $(2): ndebug or debug diff --git a/src/class_linker.cc b/src/class_linker.cc index 43f1b42013..000e2a5280 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -1344,6 +1344,9 @@ void ClassLinker::LinkOatCodeFor(Method* method) { } if (method->GetInvokeStub() == NULL) { method->SetInvokeStub(oat_method.GetInvokeStub()); +#if defined(ART_USE_LLVM_COMPILER) + method->SetProxyStub(oat_method.GetProxyStub()); +#endif } } } @@ -2297,8 +2300,7 @@ Method* ClassLinker::CreateProxyMethod(SirtRef<Class>& klass, SirtRef<Method>& p #if !defined(ART_USE_LLVM_COMPILER) method->SetCode(reinterpret_cast<void*>(art_proxy_invoke_handler)); #else - method->SetCode(reinterpret_cast<const void*>( - static_cast<uintptr_t>(compiler_llvm::special_stub::kProxyStub))); + method->SetCode(prototype->GetProxyStub()); #endif return method; diff --git a/src/common_test.h b/src/common_test.h index 3b31bd440a..b03d4d6092 100644 --- a/src/common_test.h +++ b/src/common_test.h @@ -210,6 +210,7 @@ class CommonTest : public testing::Test { 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) #endif ); diff --git a/src/compiled_method.cc b/src/compiled_method.cc index 89b54964f2..07f331cd57 100644 --- a/src/compiled_method.cc +++ b/src/compiled_method.cc @@ -180,8 +180,8 @@ const void* CompiledMethod::CodePointer(const void* code_pointer, } #if defined(ART_USE_LLVM_COMPILER) -CompiledInvokeStub::CompiledInvokeStub(uint16_t elf_idx, uint16_t elf_func_idx) - : elf_idx_(elf_idx), elf_func_idx_(elf_func_idx) { +CompiledInvokeStub::CompiledInvokeStub(uint16_t elf_idx) + : elf_idx_(elf_idx) { } #endif diff --git a/src/compiled_method.h b/src/compiled_method.h index 96dfa00c2d..f436214953 100644 --- a/src/compiled_method.h +++ b/src/compiled_method.h @@ -21,6 +21,7 @@ #include "instruction_set.h" #include "utils.h" +#include "UniquePtr.h" namespace llvm { class Function; @@ -120,20 +121,33 @@ class CompiledInvokeStub { public: explicit CompiledInvokeStub(std::vector<uint8_t>& code); #if defined(ART_USE_LLVM_COMPILER) - explicit CompiledInvokeStub(uint16_t elf_idx, uint16_t elf_func_idx); + explicit CompiledInvokeStub(uint16_t elf_idx); #endif ~CompiledInvokeStub(); const std::vector<uint8_t>& GetCode() const; - uint16_t GetElfIndex() const { + uint16_t GetStubElfIndex() const { DCHECK(IsExecutableInElf()); return elf_idx_; } - uint16_t GetElfFuncIndex() const { + uint16_t GetInvokeStubElfFuncIndex() const { DCHECK(IsExecutableInElf()); - return elf_func_idx_; + return invoke_stub_elf_func_idx_; + } + + uint16_t GetProxyStubElfFuncIndex() const { + DCHECK(IsExecutableInElf()); + return proxy_stub_elf_func_idx_; + } + + void SetInvokeStub(uint16_t invoke_stub_elf_func_idx) { + invoke_stub_elf_func_idx_ = invoke_stub_elf_func_idx; + } + + void SetProxyStub(uint16_t proxy_stub_elf_func_idx) { + proxy_stub_elf_func_idx_ = proxy_stub_elf_func_idx; } bool IsExecutableInElf() const { @@ -143,7 +157,8 @@ class CompiledInvokeStub { private: std::vector<uint8_t> code_; uint16_t elf_idx_; - uint16_t elf_func_idx_; + uint16_t invoke_stub_elf_func_idx_; + uint16_t proxy_stub_elf_func_idx_; }; } // namespace art diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc index 6d30912ee2..95e9803f68 100644 --- a/src/compiler_llvm/compiler_llvm.cc +++ b/src/compiler_llvm/compiler_llvm.cc @@ -30,7 +30,7 @@ #include "oat_compilation_unit.h" #include "oat_file.h" #include "stl_util.h" -#include "upcall_compiler.h" +#include "stub_compiler.h" #include <llvm/LinkAllPasses.h> #include <llvm/LinkAllVMCore.h> @@ -225,8 +225,8 @@ const void* CompilerLLVM::GetMethodCodeAddr(const CompiledMethod* cm) const { const Method::InvokeStub* CompilerLLVM:: GetMethodInvokeStubAddr(const CompiledInvokeStub* cm) const { - return elf_loader_->GetMethodInvokeStubAddr(cm->GetElfIndex(), - cm->GetElfFuncIndex()); + return elf_loader_->GetMethodInvokeStubAddr(cm->GetStubElfIndex(), + cm->GetInvokeStubElfFuncIndex()); } @@ -279,10 +279,15 @@ CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static, MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_); - UniquePtr<UpcallCompiler> upcall_compiler( - new UpcallCompiler(curr_cunit_, *compiler_)); + UniquePtr<StubCompiler> stub_compiler( + new StubCompiler(curr_cunit_, *compiler_)); - return upcall_compiler->CreateStub(is_static, shorty); + CompiledInvokeStub* compiled_stub = new CompiledInvokeStub(curr_cunit_->GetElfIndex()); + + compiled_stub->SetInvokeStub(stub_compiler->CreateInvokeStub(is_static, shorty)); + compiled_stub->SetProxyStub(stub_compiler->CreateProxyStub(is_static, shorty)); + + return compiled_stub; } } // namespace compiler_llvm diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc index 620ba3904c..cd79dcb7bf 100644 --- a/src/compiler_llvm/method_compiler.cc +++ b/src/compiler_llvm/method_compiler.cc @@ -72,7 +72,7 @@ MethodCompiler::MethodCompiler(CompilationUnit* cunit, basic_blocks_(code_item_->insns_size_in_code_units_), basic_block_landing_pads_(code_item_->tries_size_, NULL), basic_block_unwind_(NULL), basic_block_unreachable_(NULL), - shadow_frame_(NULL), jvalue_temp_(NULL), old_shadow_frame_(NULL), + shadow_frame_(NULL), old_shadow_frame_(NULL), already_pushed_shadow_frame_(NULL), shadow_frame_size_(0), elf_func_idx_(cunit_->AcquireUniqueElfFuncIndex()) { } @@ -168,7 +168,6 @@ void MethodCompiler::EmitPrologue() { #endif irb_.SetInsertPoint(basic_block_alloca_); - jvalue_temp_ = irb_.CreateAlloca(irb_.getJValueTy()); // Create Shadow Frame if (method_info_.need_shadow_frame) { @@ -2880,10 +2879,7 @@ void MethodCompiler::EmitInsn_Invoke(uint32_t dex_pc, llvm::BasicBlock* block_stub = CreateBasicBlockWithDexPC(dex_pc, "stub"); llvm::BasicBlock* block_continue = CreateBasicBlockWithDexPC(dex_pc, "cont"); - llvm::Value* code_addr_int = irb_.CreatePtrToInt(code_addr, irb_.getPtrEquivIntTy()); - llvm::Value* max_stub_int = irb_.getPtrEquivInt(special_stub::kMaxSpecialStub); - llvm::Value* is_stub = irb_.CreateICmpULT(code_addr_int, max_stub_int); - irb_.CreateCondBr(is_stub, block_stub, block_normal, kUnlikely); + irb_.CreateCondBr(irb_.CreateIsNull(code_addr), block_stub, block_normal, kUnlikely); irb_.SetInsertPoint(block_normal); @@ -2898,42 +2894,15 @@ void MethodCompiler::EmitInsn_Invoke(uint32_t dex_pc, irb_.SetInsertPoint(block_stub); - { - { // lazy link - // TODO: Remove this after we solve the link problem. - llvm::BasicBlock* block_proxy_stub = CreateBasicBlockWithDexPC(dex_pc, "proxy"); - llvm::BasicBlock* block_link = CreateBasicBlockWithDexPC(dex_pc, "link"); - - irb_.CreateCondBr(irb_.CreateIsNull(code_addr), block_link, block_proxy_stub, kUnlikely); - - - irb_.SetInsertPoint(block_link); - code_addr = EmitFixStub(callee_method_object_addr, callee_method_idx, is_static); - - EmitGuard_ExceptionLandingPad(dex_pc, false); - - llvm::Value* retval = irb_.CreateCall(code_addr, args); - if (ret_shorty != 'V') { - EmitStoreDalvikRetValReg(ret_shorty, kAccurate, retval); - } - irb_.CreateBr(block_continue); + { // lazy link + // TODO: Remove this after we solve the link problem. + code_addr = EmitFixStub(callee_method_object_addr, callee_method_idx, is_static); + EmitGuard_ExceptionLandingPad(dex_pc, false); - irb_.SetInsertPoint(block_proxy_stub); - } - { // proxy stub - if (ret_shorty != 'V') { - args.push_back(jvalue_temp_); - } - // TODO: Remove this after we solve the proxy trampoline calling convention problem. - irb_.CreateCall(irb_.GetRuntime(ProxyInvokeHandler), args); - if (ret_shorty != 'V') { - llvm::Type* accurate_ret_type = irb_.getJType(ret_shorty, kAccurate); - llvm::Value* result_addr = - irb_.CreateBitCast(jvalue_temp_, accurate_ret_type->getPointerTo()); - llvm::Value* retval = irb_.CreateLoad(result_addr, kTBAAStackTemp); - EmitStoreDalvikRetValReg(ret_shorty, kAccurate, retval); - } + llvm::Value* retval = irb_.CreateCall(code_addr, args); + if (ret_shorty != 'V') { + EmitStoreDalvikRetValReg(ret_shorty, kAccurate, retval); } } irb_.CreateBr(block_continue); diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h index 44ab863c4a..190782388c 100644 --- a/src/compiler_llvm/method_compiler.h +++ b/src/compiler_llvm/method_compiler.h @@ -473,7 +473,6 @@ class MethodCompiler { llvm::BasicBlock* basic_block_unreachable_; llvm::AllocaInst* shadow_frame_; - llvm::AllocaInst* jvalue_temp_; llvm::Value* old_shadow_frame_; llvm::Value* already_pushed_shadow_frame_; diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc index 578f84e072..59124ce706 100644 --- a/src/compiler_llvm/runtime_support_llvm.cc +++ b/src/compiler_llvm/runtime_support_llvm.cc @@ -654,7 +654,7 @@ void art_proxy_invoke_handler_from_code(Method* proxy_method, ...) { va_start(ap, proxy_method); Object* receiver = va_arg(ap, Object*); - Thread* thread = art_get_current_thread_from_code(); + Thread* thread = va_arg(ap, Thread*); MethodHelper proxy_mh(proxy_method); const size_t num_params = proxy_mh.NumArgs(); diff --git a/src/compiler_llvm/runtime_support_llvm.h b/src/compiler_llvm/runtime_support_llvm.h index bca9528a67..3e8d96d2a3 100644 --- a/src/compiler_llvm/runtime_support_llvm.h +++ b/src/compiler_llvm/runtime_support_llvm.h @@ -19,16 +19,6 @@ namespace art { -namespace compiler_llvm { -namespace special_stub { - enum SpecialStub { - kProxyStub = 16, - kMaxSpecialStub - }; -} -} // namespace compiler_llvm - - class Method; class Object; diff --git a/src/compiler_llvm/upcall_compiler.cc b/src/compiler_llvm/stub_compiler.cc index 0f3a92e084..2cf5141d6e 100644 --- a/src/compiler_llvm/upcall_compiler.cc +++ b/src/compiler_llvm/stub_compiler.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "upcall_compiler.h" +#include "stub_compiler.h" #include "compilation_unit.h" #include "compiled_method.h" @@ -40,21 +40,21 @@ namespace compiler_llvm { using namespace runtime_support; -UpcallCompiler::UpcallCompiler(CompilationUnit* cunit, Compiler& compiler) +StubCompiler::StubCompiler(CompilationUnit* cunit, Compiler& compiler) : cunit_(cunit), compiler_(&compiler), module_(cunit_->GetModule()), - context_(cunit_->GetLLVMContext()), irb_(*cunit_->GetIRBuilder()), - elf_func_idx_(cunit_->AcquireUniqueElfFuncIndex()) { + context_(cunit_->GetLLVMContext()), irb_(*cunit_->GetIRBuilder()) { } -CompiledInvokeStub* UpcallCompiler::CreateStub(bool is_static, - char const* shorty) { +uint16_t StubCompiler::CreateInvokeStub(bool is_static, + char const* shorty) { + uint16_t elf_func_idx = cunit_->AcquireUniqueElfFuncIndex(); CHECK_NE(shorty, static_cast<char const*>(NULL)); size_t shorty_size = strlen(shorty); // Function name - std::string func_name(ElfFuncName(elf_func_idx_)); + std::string func_name(ElfFuncName(elf_func_idx)); // Get argument types llvm::Type* arg_types[] = { @@ -189,7 +189,80 @@ CompiledInvokeStub* UpcallCompiler::CreateStub(bool is_static, // store ret_addr, and ret_void. Beside, we guess that we have to use // 50 bytes to represent one LLVM instruction. - return new CompiledInvokeStub(cunit_->GetElfIndex(), elf_func_idx_); + return elf_func_idx; +} + +uint16_t StubCompiler::CreateProxyStub(bool is_static, + char const* shorty) { + // Static method dosen't need proxy stub. + if (is_static) { + return NULL; + } + + CHECK_NE(shorty, static_cast<char const*>(NULL)); + size_t shorty_size = strlen(shorty); + + uint16_t elf_func_idx = cunit_->AcquireUniqueElfFuncIndex(); + + // Function name + std::string func_name(ElfFuncName(elf_func_idx)); + + // Accurate function type + llvm::Type* accurate_ret_type = irb_.getJType(shorty[0], kAccurate); + std::vector<llvm::Type*> accurate_arg_types; + accurate_arg_types.push_back(irb_.getJObjectTy()); // method + accurate_arg_types.push_back(irb_.getJObjectTy()); // this + for (size_t i = 1; i < shorty_size; ++i) { + accurate_arg_types.push_back(irb_.getJType(shorty[i], kAccurate)); + } + llvm::FunctionType* accurate_func_type = + llvm::FunctionType::get(accurate_ret_type, accurate_arg_types, false); + + // Create function + llvm::Function* func = + llvm::Function::Create(accurate_func_type, llvm::Function::ExternalLinkage, + func_name, module_); + + // Create basic block for the body of this function + llvm::BasicBlock* block_body = + llvm::BasicBlock::Create(*context_, "proxy", func); + irb_.SetInsertPoint(block_body); + + // JValue for proxy return + llvm::AllocaInst* jvalue_temp = irb_.CreateAlloca(irb_.getJValueTy()); + + // Load actual arguments + llvm::Function::arg_iterator arg_iter = func->arg_begin(); + std::vector<llvm::Value*> args; + args.push_back(arg_iter++); // method + args.push_back(arg_iter++); // this + args.push_back(irb_.Runtime().EmitGetCurrentThread()); // thread + for (size_t i = 1; i < shorty_size; ++i) { + args.push_back(arg_iter++); + } + if (shorty[0] != 'V') { + args.push_back(jvalue_temp); + } + + // Call ProxyInvokeHandler + // TODO: Partial inline ProxyInvokeHandler, don't use VarArg. + irb_.CreateCall(irb_.GetRuntime(ProxyInvokeHandler), args); + if (shorty[0] != 'V') { + llvm::Value* result_addr = + irb_.CreateBitCast(jvalue_temp, accurate_ret_type->getPointerTo()); + llvm::Value* retval = irb_.CreateLoad(result_addr, kTBAAStackTemp); + irb_.CreateRet(retval); + } else { + irb_.CreateRetVoid(); + } + + // Verify the generated function + VERIFY_LLVM_FUNCTION(*func); + + // Add the memory usage approximation of the compilation unit + cunit_->AddMemUsageApproximation((shorty_size + 2) * 50); + + return elf_func_idx; } diff --git a/src/compiler_llvm/upcall_compiler.h b/src/compiler_llvm/stub_compiler.h index 9cb49b0bd6..4b49ec49a9 100644 --- a/src/compiler_llvm/upcall_compiler.h +++ b/src/compiler_llvm/stub_compiler.h @@ -14,13 +14,14 @@ * limitations under the License. */ -#ifndef ART_SRC_COMPILER_LLVM_UPCALL_COMPILER_H_ -#define ART_SRC_COMPILER_LLVM_UPCALL_COMPILER_H_ +#ifndef ART_SRC_COMPILER_LLVM_STUB_COMPILER_H_ +#define ART_SRC_COMPILER_LLVM_STUB_COMPILER_H_ #include <stdint.h> namespace art { class CompiledInvokeStub; + class CompiledProxyStub; class Compiler; } @@ -36,11 +37,12 @@ class CompilationUnit; class CompilerLLVM; class IRBuilder; -class UpcallCompiler { +class StubCompiler { public: - UpcallCompiler(CompilationUnit* cunit, Compiler& compiler); + StubCompiler(CompilationUnit* cunit, Compiler& compiler); - CompiledInvokeStub* CreateStub(bool is_static, char const* shorty); + uint16_t CreateInvokeStub(bool is_static, char const* shorty); + uint16_t CreateProxyStub(bool is_static, char const* shorty); private: CompilationUnit* cunit_; @@ -48,7 +50,6 @@ class UpcallCompiler { llvm::Module* module_; llvm::LLVMContext* context_; IRBuilder& irb_; - uint16_t elf_func_idx_; }; @@ -56,4 +57,4 @@ class UpcallCompiler { } // namespace art -#endif // ART_SRC_COMPILER_LLVM_UPCALL_COMPILER_H_ +#endif // ART_SRC_COMPILER_LLVM_STUB_COMPILER_H_ diff --git a/src/oat.cc b/src/oat.cc index bf05f7177b..d5aaf6489b 100644 --- a/src/oat.cc +++ b/src/oat.cc @@ -176,7 +176,8 @@ OatMethodOffsets::OatMethodOffsets(uint32_t code_offset, , 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 invoke_stub_elf_func_idx, + uint16_t proxy_stub_elf_func_idx #endif ) : code_offset_(code_offset), @@ -191,7 +192,8 @@ OatMethodOffsets::OatMethodOffsets(uint32_t code_offset, , 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) + invoke_stub_elf_func_idx_(invoke_stub_elf_func_idx), + proxy_stub_elf_func_idx_(proxy_stub_elf_func_idx) #endif {} @@ -86,7 +86,8 @@ class PACKED OatMethodOffsets { , 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 invoke_stub_elf_func_idx, + uint16_t proxy_stub_elf_func_idx #endif ); ~OatMethodOffsets(); @@ -105,6 +106,7 @@ class PACKED OatMethodOffsets { uint16_t code_elf_func_idx_; uint16_t invoke_stub_elf_idx_; uint16_t invoke_stub_elf_func_idx_; + uint16_t proxy_stub_elf_func_idx_; #endif }; diff --git a/src/oat_file.cc b/src/oat_file.cc index 7196222ecb..32e3b69ebc 100644 --- a/src/oat_file.cc +++ b/src/oat_file.cc @@ -314,7 +314,8 @@ const OatFile::OatMethod OatFile::OatClass::GetOatMethod(uint32_t method_index) 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.invoke_stub_elf_func_idx_, + oat_method_offsets.proxy_stub_elf_func_idx_ #endif ); } @@ -333,7 +334,8 @@ OatFile::OatMethod::OatMethod(const byte* base, 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 invoke_stub_elf_func_idx, + const uint16_t proxy_stub_elf_func_idx #endif ) : begin_(base), @@ -350,7 +352,8 @@ OatFile::OatMethod::OatMethod(const byte* base, 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) + invoke_stub_elf_func_idx_(invoke_stub_elf_func_idx), + proxy_stub_elf_func_idx_(proxy_stub_elf_func_idx) #endif { #ifndef NDEBUG @@ -444,6 +447,18 @@ uint32_t OatFile::OatMethod::GetInvokeStubSize() const { } } +#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(invoke_stub_elf_idx_, + proxy_stub_elf_func_idx_); + } + return stub; +} +#endif + void OatFile::OatMethod::LinkMethodPointers(Method* method) const { CHECK(method != NULL); method->SetCode(GetCode()); @@ -454,6 +469,9 @@ void OatFile::OatMethod::LinkMethodPointers(Method* method) const { method->SetVmapTable(GetVmapTable()); method->SetGcMap(GetGcMap()); // Note, used by native methods in work around JNI mode. method->SetInvokeStub(GetInvokeStub()); +#if defined(ART_USE_LLVM_COMPILER) + method->SetProxyStub(GetProxyStub()); +#endif } void OatFile::OatMethod::LinkMethodOffsets(Method* method) const { diff --git a/src/oat_file.h b/src/oat_file.h index 0b1ebac884..e958c4d1c2 100644 --- a/src/oat_file.h +++ b/src/oat_file.h @@ -150,6 +150,10 @@ class OatFile { const Method::InvokeStub* GetInvokeStub() const; uint32_t GetInvokeStubSize() const; +#if defined(ART_USE_LLVM_COMPILER) + const void* GetProxyStub() const; +#endif + ~OatMethod(); // Create an OatMethod with offsets relative to the given base address @@ -167,7 +171,8 @@ class OatFile { 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 invoke_stub_elf_func_idx, + const uint16_t proxy_stub_elf_func_idx #endif ); @@ -198,6 +203,7 @@ class OatFile { uint16_t code_elf_func_idx_; uint16_t invoke_stub_elf_idx_; uint16_t invoke_stub_elf_func_idx_; + uint16_t proxy_stub_elf_func_idx_; #endif friend class OatClass; diff --git a/src/oat_writer.cc b/src/oat_writer.cc index ffdb0c8c2d..f5c0816923 100644 --- a/src/oat_writer.cc +++ b/src/oat_writer.cc @@ -273,6 +273,7 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, #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_func_idx = static_cast<uint16_t>(-1u); #endif CompiledMethod* compiled_method = @@ -365,10 +366,18 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, const CompiledInvokeStub* compiled_invoke_stub = compiler_->FindInvokeStub(is_static, shorty); if (compiled_invoke_stub != NULL) { if (compiled_invoke_stub->IsExecutableInElf()) { +<<<<<<< HEAD #if defined(ART_USE_LLVM_COMPILER) invoke_stub_elf_idx = compiled_invoke_stub->GetElfIndex(); invoke_stub_elf_func_idx = compiled_invoke_stub->GetElfFuncIndex(); #endif +======= + invoke_stub_elf_idx = compiled_invoke_stub->GetStubElfIndex(); + invoke_stub_elf_func_idx = compiled_invoke_stub->GetInvokeStubElfFuncIndex(); + if (!is_static) { + proxy_stub_elf_func_idx = compiled_invoke_stub->GetProxyStubElfFuncIndex(); + } +>>>>>>> f3b0b35... Implement proxy stub for compiler_llvm. } else { offset = CompiledMethod::AlignCode(offset, compiler_->GetInstructionSet()); DCHECK_ALIGNED(offset, kArmAlignment); @@ -403,7 +412,8 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, , code_elf_idx, code_elf_func_idx, invoke_stub_elf_idx, - invoke_stub_elf_func_idx + invoke_stub_elf_func_idx, + proxy_stub_elf_func_idx #endif ); diff --git a/src/object.h b/src/object.h index f5970f65df..e787933744 100644 --- a/src/object.h +++ b/src/object.h @@ -861,6 +861,22 @@ class MANAGED Method : public Object { return OFFSET_OF_OBJECT_MEMBER(Method, invoke_stub_); } +#if defined(ART_USE_LLVM_COMPILER) + // Proxy stub entry point + const void* GetProxyStub() const { + // NOTE: LLVM doesn't use vmap table, so we reuse it for proxy stub. + const void* result = GetFieldPtr<const void*>( + OFFSET_OF_OBJECT_MEMBER(Method, vmap_table_), false); + // TODO: DCHECK(result != NULL); should be ahead of time compiled + return result; + } + + void SetProxyStub(const void* proxy_stub) { + SetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(Method, vmap_table_), + proxy_stub, false); + } +#endif + static MemberOffset GetMethodIndexOffset() { return OFFSET_OF_OBJECT_MEMBER(Method, method_index_); } |