summaryrefslogtreecommitdiff
path: root/src/compiler_llvm/method_compiler.cc
diff options
context:
space:
mode:
author TDYa127 <tdy@google.com> 2012-04-11 05:57:28 -0700
committer Shih-wei Liao <sliao@google.com> 2012-04-11 11:01:21 -0700
commit5bb8601175bbb9cd761c715f4ba04f84d65e913b (patch)
tree441c62e467b6c7a355d9ad65ea88a923abbb409b /src/compiler_llvm/method_compiler.cc
parent933abf8ce64e522b1c45b191b796bf2208a760d9 (diff)
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
Diffstat (limited to 'src/compiler_llvm/method_compiler.cc')
-rw-r--r--src/compiler_llvm/method_compiler.cc68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 50ed471ed5..fb6cc19343 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 @@ void MethodCompiler::EmitInsn_Invoke(uint32_t dex_pc,
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 @@ void MethodCompiler::EmitInsn_Invoke(uint32_t dex_pc,
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));
}