Remove CADMs from LLVM code generator.
Change-Id: Iafe3ff9f528c6a1573b7358b16566af745ff3c9f
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 714b6e5..294d005 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -656,11 +656,11 @@
break;
case Instruction::INVOKE_DIRECT:
- EmitInsn_InvokeStaticDirect(ARGS, /* is_range */ false, /* is_static */ false);
+ EmitInsn_InvokeStaticDirect(ARGS, kDirect, /* is_range */ false);
break;
case Instruction::INVOKE_STATIC:
- EmitInsn_InvokeStaticDirect(ARGS, /* is_range */ false, /* is_static */ true);
+ EmitInsn_InvokeStaticDirect(ARGS, kStatic, /* is_range */ false);
break;
case Instruction::INVOKE_INTERFACE:
@@ -676,11 +676,11 @@
break;
case Instruction::INVOKE_DIRECT_RANGE:
- EmitInsn_InvokeStaticDirect(ARGS, /* is_range */ true, /* is_static */ false);
+ EmitInsn_InvokeStaticDirect(ARGS, kDirect, true);
break;
case Instruction::INVOKE_STATIC_RANGE:
- EmitInsn_InvokeStaticDirect(ARGS, /* is_range */ true, /* is_static */ true);
+ EmitInsn_InvokeStaticDirect(ARGS, kStatic, true);
break;
case Instruction::INVOKE_INTERFACE_RANGE:
@@ -2859,16 +2859,24 @@
void MethodCompiler::EmitInsn_InvokeStaticDirect(uint32_t dex_pc,
Instruction const* insn,
- bool is_range,
- bool is_static) {
+ InvokeType invoke_type,
+ bool is_range) {
Instruction::DecodedInstruction dec_insn(insn);
uint32_t callee_method_idx = dec_insn.vB_;
- // Find the method object at compile time
- Method* callee_method = dex_cache_->GetResolvedMethod(callee_method_idx);
- CHECK_NE(callee_method, static_cast<Method*>(NULL));
+ bool is_static = (invoke_type == kStatic);
+
+ UniquePtr<OatCompilationUnit> callee_oatcompilation_unit(
+ oatcompilation_unit_->GetCallee(callee_method_idx, is_static ? kAccStatic : 0));
+
+ int vtable_idx = -1; // Currently unused
+ bool is_fast_path = compiler_->
+ ComputeInvokeInfo(callee_method_idx, callee_oatcompilation_unit.get(),
+ invoke_type, vtable_idx);
+
+ CHECK(is_fast_path) << "Slow path for invoke static/direct is unimplemented";
llvm::Value* this_addr = NULL;
@@ -2879,34 +2887,14 @@
}
// Load method function pointers
-
- // TODO: Besides finding the callee function address through Code and
- // Direct Methods (CADMS) at runtime, try to find the callee function
- // through something like compiler_llvm_->GetCompiledMethod(...)
- // so that we can perform inlining.
-
- llvm::Value* code_addr_field_addr = NULL;
- llvm::Value* method_field_addr = NULL;
-
- EmitLoadDexCacheCodeAndDirectMethodFieldAddr(
- code_addr_field_addr, method_field_addr, callee_method_idx);
-
- // NOTE: Since CADMS are mixing int type with pointer type, we have to
- // cast the integer type to pointer type. Following code must be refined
- // when we are going to port to 64bit architecture.
-
- llvm::Value* code_addr_int = irb_.CreateLoad(code_addr_field_addr);
-
- llvm::FunctionType* callee_type =
- GetFunctionType(callee_method_idx, is_static);
-
- llvm::Value* code_addr =
- irb_.CreateIntToPtr(code_addr_int, callee_type->getPointerTo());
-
- llvm::Value* callee_method_value_int = irb_.CreateLoad(method_field_addr);
+ llvm::Value* callee_method_object_field_addr =
+ EmitLoadDexCacheResolvedMethodFieldAddr(callee_method_idx);
llvm::Value* callee_method_object_addr =
- irb_.CreateIntToPtr(callee_method_value_int, irb_.getJObjectTy());
+ irb_.CreateLoad(callee_method_object_field_addr);
+
+ llvm::Value* code_addr =
+ EmitLoadCodeAddr(callee_method_object_addr, callee_method_idx, is_static);
// Load the actual parameter
std::vector<llvm::Value*> args;
@@ -2925,8 +2913,7 @@
llvm::Value* retval = irb_.CreateCall(code_addr, args);
EmitGuard_ExceptionLandingPad(dex_pc);
- MethodHelper method_helper(callee_method);
- char ret_shorty = method_helper.GetShorty()[0];
+ char ret_shorty = callee_oatcompilation_unit->GetShorty()[0];
if (ret_shorty != 'V') {
EmitStoreDalvikRetValReg(ret_shorty, kAccurate, retval);
}
@@ -3465,28 +3452,6 @@
}
-void MethodCompiler::
-EmitLoadDexCacheCodeAndDirectMethodFieldAddr(llvm::Value*& code_field_addr,
- llvm::Value*& method_field_addr,
- uint32_t method_idx) {
- llvm::Value* cadms_dex_cache_addr =
- EmitLoadDexCacheAddr(Method::GetDexCacheCodeAndDirectMethodsOffset());
-
- llvm::Value* code_index_value =
- irb_.getPtrEquivInt(CodeAndDirectMethods::CodeIndex(method_idx));
-
- llvm::Value* method_index_value =
- irb_.getPtrEquivInt(CodeAndDirectMethods::MethodIndex(method_idx));
-
- // Return the field address
- code_field_addr = EmitArrayGEP(cadms_dex_cache_addr, code_index_value,
- irb_.getJIntTy());
-
- method_field_addr = EmitArrayGEP(cadms_dex_cache_addr, method_index_value,
- irb_.getJIntTy());
-}
-
-
llvm::Value* MethodCompiler::
EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx) {
llvm::Value* static_storage_dex_cache_addr =
@@ -3512,6 +3477,18 @@
llvm::Value* MethodCompiler::
+EmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx) {
+ llvm::Value* resolved_method_dex_cache_addr =
+ EmitLoadDexCacheAddr(Method::DexCacheResolvedMethodsOffset());
+
+ llvm::Value* method_idx_value = irb_.getPtrEquivInt(method_idx);
+
+ return EmitArrayGEP(resolved_method_dex_cache_addr, method_idx_value,
+ irb_.getJObjectTy());
+}
+
+
+llvm::Value* MethodCompiler::
EmitLoadDexCacheStringFieldAddr(uint32_t string_idx) {
llvm::Value* string_dex_cache_addr =
EmitLoadDexCacheAddr(Method::DexCacheStringsOffset());
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index de60fa3..e75e945 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -232,8 +232,8 @@
void EmitInsn_InvokeVirtual(GEN_INSN_ARGS, bool is_range);
void EmitInsn_InvokeSuper(GEN_INSN_ARGS, bool is_range);
void EmitInsn_InvokeStaticDirect(GEN_INSN_ARGS,
- bool is_range,
- bool is_static);
+ InvokeType invoke_type,
+ bool is_range);
void EmitInsn_InvokeInterface(GEN_INSN_ARGS, bool is_range);
// Unary instructions
@@ -275,15 +275,12 @@
// Dex cache code generation helper function
llvm::Value* EmitLoadDexCacheAddr(MemberOffset dex_cache_offset);
- void EmitLoadDexCacheCodeAndDirectMethodFieldAddr(
- llvm::Value*& code_addr_field_addr,
- llvm::Value*& method_field_addr,
- uint32_t method_idx);
-
llvm::Value* EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx);
llvm::Value* EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx);
+ llvm::Value* EmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx);
+
llvm::Value* EmitLoadDexCacheStringFieldAddr(uint32_t string_idx);
diff --git a/src/oat_compilation_unit.h b/src/oat_compilation_unit.h
index 9d1463e..97591a1 100644
--- a/src/oat_compilation_unit.h
+++ b/src/oat_compilation_unit.h
@@ -17,6 +17,8 @@
#ifndef ART_SRC_METHOD_UNIT_H_
#define ART_SRC_METHOD_UNIT_H_
+#include "dex_file.h"
+
#include <stdint.h>
namespace art {
@@ -37,6 +39,22 @@
method_idx_(method_idx), access_flags_(access_flags) {
}
+ OatCompilationUnit* GetCallee(uint32_t callee_method_idx,
+ uint32_t callee_access_flags) {
+ return new OatCompilationUnit(class_loader_, class_linker_, *dex_file_, *dex_cache_,
+ NULL, callee_method_idx, callee_access_flags);
+ }
+
+ char const* GetShorty() const {
+ DexFile::MethodId const& method_id = dex_file_->GetMethodId(method_idx_);
+ return dex_file_->GetMethodShorty(method_id);
+ }
+
+ char const* GetShorty(uint32_t* shorty_len) const {
+ DexFile::MethodId const& method_id = dex_file_->GetMethodId(method_idx_);
+ return dex_file_->GetMethodShorty(method_id, shorty_len);
+ }
+
public:
ClassLoader const* class_loader_;
ClassLinker* class_linker_;