Fix 044-proxy. Implement proxy for now, working on x86 and ARM.
Already added a TODO to do the assembly code for x86 and ARM for proxy.
Use LLVM .ll for multi-architecture now.
Change-Id: Ibdeeee113dcf284592e9d7769d3044438cb1e453
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 50ed471..fb6cc19 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -27,6 +27,7 @@
#include "object.h"
#include "object_utils.h"
#include "runtime_support_func.h"
+#include "runtime_support_llvm.h"
#include "shadow_frame.h"
#include "stl_util.h"
#include "stringprintf.h"
@@ -2884,6 +2885,7 @@
EmitLoadActualParameters(args, callee_method_idx, dec_insn,
arg_fmt, is_static);
+#if 0
// Invoke callee
EmitUpdateLineNumFromDexPC(dex_pc);
llvm::Value* retval = irb_.CreateCall(code_addr, args);
@@ -2897,6 +2899,72 @@
if (ret_shorty != 'V') {
EmitStoreDalvikRetValReg(ret_shorty, kAccurate, retval);
}
+#else
+ uint32_t callee_access_flags = is_static ? kAccStatic : 0;
+ UniquePtr<OatCompilationUnit> callee_oat_compilation_unit(
+ oat_compilation_unit_->GetCallee(callee_method_idx, callee_access_flags));
+
+ char ret_shorty = callee_oat_compilation_unit->GetShorty()[0];
+
+
+ EmitUpdateLineNumFromDexPC(dex_pc);
+
+
+ llvm::BasicBlock* block_normal = CreateBasicBlockWithDexPC(dex_pc, "normal");
+ llvm::BasicBlock* block_proxy_stub = CreateBasicBlockWithDexPC(dex_pc, "proxy");
+ llvm::BasicBlock* block_continue = CreateBasicBlockWithDexPC(dex_pc, "cont");
+
+ llvm::Type* accurate_ret_type = irb_.getJType(ret_shorty, kAccurate);
+ llvm::Value* retval_addr = NULL;
+ if (ret_shorty != 'V') {
+ retval_addr = irb_.CreateAlloca(accurate_ret_type);
+ }
+
+
+ // TODO: Remove this after we solve the proxy trampoline calling convention problem.
+ llvm::Value* code_addr_int = irb_.CreatePtrToInt(code_addr, irb_.getPtrEquivIntTy());
+ llvm::Value* proxy_stub_int = irb_.getPtrEquivInt(special_stub::kProxyStub);
+ llvm::Value* is_proxy_stub = irb_.CreateICmpEQ(code_addr_int, proxy_stub_int);
+ irb_.CreateCondBr(is_proxy_stub, block_proxy_stub, block_normal);
+
+
+ irb_.SetInsertPoint(block_normal);
+ {
+ // Invoke callee
+ llvm::Value* result = irb_.CreateCall(code_addr, args);
+ if (ret_shorty != 'V') {
+ irb_.CreateStore(result, retval_addr);
+ }
+ }
+ irb_.CreateBr(block_continue);
+
+
+ irb_.SetInsertPoint(block_proxy_stub);
+ {
+ llvm::Value* temp_space_addr;
+ if (ret_shorty != 'V') {
+ temp_space_addr = irb_.CreateAlloca(irb_.getJValueTy());
+ args.push_back(temp_space_addr);
+ }
+ irb_.CreateCall(irb_.GetRuntime(ProxyInvokeHandler), args);
+ if (ret_shorty != 'V') {
+ llvm::Value* result_addr =
+ irb_.CreateBitCast(temp_space_addr, accurate_ret_type->getPointerTo());
+ llvm::Value* retval = irb_.CreateLoad(result_addr);
+ irb_.CreateStore(retval, retval_addr);
+ }
+ }
+ irb_.CreateBr(block_continue);
+
+
+ irb_.SetInsertPoint(block_continue);
+
+ if (ret_shorty != 'V') {
+ llvm::Value* retval = irb_.CreateLoad(retval_addr);
+ EmitStoreDalvikRetValReg(ret_shorty, kAccurate, retval);
+ }
+ EmitGuard_ExceptionLandingPad(dex_pc);
+#endif
irb_.CreateBr(GetNextBasicBlock(dex_pc));
}