Implement partial sharpening for LLVM.
Change-Id: I0c6953d6428edda71230c0088b9e0c9decada3b7
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 8e592fe..8d6b251 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -36,9 +36,12 @@
#include <iomanip>
#include <llvm/BasicBlock.h>
+#include <llvm/DerivedTypes.h>
#include <llvm/Function.h>
#include <llvm/GlobalVariable.h>
#include <llvm/Intrinsics.h>
+#include <llvm/Module.h>
+#include <llvm/Type.h>
namespace art {
namespace compiler_llvm {
@@ -2806,7 +2809,7 @@
// Compute invoke related information for compiler decision
int vtable_idx = -1;
uintptr_t direct_code = 0; // Currently unused
- uintptr_t direct_method = 0; // Currently unused
+ uintptr_t direct_method = 0;
bool is_fast_path = compiler_->
ComputeInvokeInfo(callee_method_idx, oat_compilation_unit_,
invoke_type, vtable_idx, direct_code, direct_method);
@@ -2834,8 +2837,15 @@
switch (invoke_type) {
case kStatic:
case kDirect:
- callee_method_object_addr =
- EmitLoadSDCalleeMethodObjectAddr(callee_method_idx);
+ if (direct_method != 0u &&
+ direct_method != static_cast<uintptr_t>(-1)) {
+ callee_method_object_addr =
+ EmitLoadSDCalleeDirectMethodObjectAddr(callee_method_idx,
+ direct_method);
+ } else {
+ callee_method_object_addr =
+ EmitLoadSDCalleeMethodObjectAddr(callee_method_idx);
+ }
break;
case kVirtual:
@@ -2982,6 +2992,27 @@
llvm::Value* MethodCompiler::
+EmitLoadSDCalleeDirectMethodObjectAddr(uint32_t callee_method_idx,
+ uintptr_t direct_method) {
+ std::string direct_method_name(
+ StringPrintf("ArtMethodObject_%08lx",
+ static_cast<unsigned long>(direct_method)));
+
+ llvm::GlobalVariable* direct_method_addr =
+ module_->getGlobalVariable(direct_method_name);
+
+ if (direct_method_addr == NULL) {
+ direct_method_addr =
+ new llvm::GlobalVariable(*module_, irb_.getJObjectTy()->getElementType(),
+ false, llvm::GlobalVariable::ExternalLinkage,
+ NULL, direct_method_name);
+ }
+
+ return direct_method_addr;
+}
+
+
+llvm::Value* MethodCompiler::
EmitLoadSDCalleeMethodObjectAddr(uint32_t callee_method_idx) {
llvm::Value* callee_method_object_field_addr =
EmitLoadDexCacheResolvedMethodFieldAddr(callee_method_idx);