summaryrefslogtreecommitdiff
path: root/src/compiler_llvm
diff options
context:
space:
mode:
author TDYa127 <tdy@google.com> 2012-03-19 02:58:02 -0700
committer Shih-wei Liao <sliao@google.com> 2012-03-26 21:04:42 -0700
commit31a9933bfe68ef1241c74c6586b3bc259a0244ea (patch)
tree4eedffbb35e7840ee8e3976b216d0758c4655c39 /src/compiler_llvm
parentf7015fd55a8dc969ac2440ffc829a6b4d942fb5a (diff)
Fix GEP & refactor compiler_llvm::JniCompiler.
Three major changes: o Use member offset instead of hard coded constant. We use GetElementPtr before, but it needs the ordinal number of field. If we reorder the members, we need to correct all the constants. o Remove the type parameter in the StoreToObjectOffset(). LLVM IR is strongly typed, we can get the type by the new_value. o Add more comments. (cherry picked from commit de9069a7768bd60bcdbcfb37d9b245f255ba8570) Change-Id: I833c0be3177f7b7e5a59ddf6d9d6c06ee1e95ce6
Diffstat (limited to 'src/compiler_llvm')
-rw-r--r--src/compiler_llvm/jni_compiler.cc78
-rw-r--r--src/compiler_llvm/jni_compiler.h3
2 files changed, 45 insertions, 36 deletions
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
index ad730dcc81..255e99a36b 100644
--- a/src/compiler_llvm/jni_compiler.cc
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -27,6 +27,7 @@
#include "object.h"
#include "runtime.h"
#include "runtime_support_func.h"
+#include "shadow_frame.h"
#include "utils_llvm.h"
#include <llvm/Analysis/Verifier.h>
@@ -90,6 +91,7 @@ CompiledMethod* JniCompiler::Compile() {
// Start to build IR
irb_.SetInsertPoint(basic_block_);
+ // Get thread object
llvm::Value* thread_object_addr =
irb_.CreateCall(irb_.GetRuntime(runtime_support::GetCurrentThread));
@@ -100,35 +102,28 @@ CompiledMethod* JniCompiler::Compile() {
// Zero-initialization of the shadow frame
llvm::ConstantAggregateZero* zero_initializer =
llvm::ConstantAggregateZero::get(shadow_frame_type);
-
irb_.CreateStore(zero_initializer, shadow_frame_);
- // Variables for GetElementPtr
- llvm::Constant* zero = irb_.getInt32(0);
- llvm::Value* gep_index[] = {
- zero, // No displacement for shadow frame pointer
- zero, // Get the %ArtFrame data structure
- NULL,
- };
-
// Store the method pointer
- gep_index[2] = irb_.getInt32(2);
- llvm::Value* method_field_addr = irb_.CreateGEP(shadow_frame_, gep_index);
+ llvm::Value* method_field_addr =
+ irb_.CreatePtrDisp(shadow_frame_,
+ irb_.getPtrEquivInt(ShadowFrame::MethodOffset()),
+ irb_.getJObjectTy()->getPointerTo());
irb_.CreateStore(method_object_addr, method_field_addr);
// Store the number of the pointer slots
- gep_index[2] = irb_.getInt32(0);
- llvm::Value* size_field_addr = irb_.CreateGEP(shadow_frame_, gep_index);
- llvm::ConstantInt* sirt_size_value = irb_.getInt32(sirt_size);
- irb_.CreateStore(sirt_size_value, size_field_addr);
+ StoreToObjectOffset(shadow_frame_,
+ ShadowFrame::NumberOfReferencesOffset(),
+ irb_.getInt32(sirt_size));
// Push the shadow frame
llvm::Value* shadow_frame_upcast = irb_.CreateConstGEP2_32(shadow_frame_, 0, 0);
irb_.CreateCall(irb_.GetRuntime(runtime_support::PushShadowFrame), shadow_frame_upcast);
// Set top of managed stack to the method field in the SIRT
- StoreToObjectOffset(thread_object_addr, Thread::TopOfManagedStackOffset().Int32Value(),
- method_field_addr->getType(), method_field_addr);
+ StoreToObjectOffset(thread_object_addr,
+ Thread::TopOfManagedStackOffset().Int32Value(),
+ method_field_addr);
// Get JNIEnv
llvm::Value* jni_env_object_addr = LoadFromObjectOffset(thread_object_addr,
@@ -136,8 +131,9 @@ CompiledMethod* JniCompiler::Compile() {
irb_.getJObjectTy());
// Set thread state to kNative
- StoreToObjectOffset(thread_object_addr, Thread::StateOffset().Int32Value(),
- irb_.getInt32Ty(), irb_.getInt32(Thread::kNative));
+ StoreToObjectOffset(thread_object_addr,
+ Thread::StateOffset().Int32Value(),
+ irb_.getInt32(Thread::kNative));
// Get callee code_addr
llvm::Value* code_addr =
@@ -149,26 +145,35 @@ CompiledMethod* JniCompiler::Compile() {
// Load actual parameters
std::vector<llvm::Value*> args;
+ // The 1st parameter: JNIEnv*
args.push_back(jni_env_object_addr);
- //args.push_back(method_object_addr); // method object for callee
- // Store arguments to SIRT, and push back to args
- gep_index[1] = irb_.getInt32(1); // SIRT
+ // Variables for GetElementPtr
+ llvm::Value* gep_index[] = {
+ irb_.getInt32(0), // No displacement for shadow frame pointer
+ irb_.getInt32(1), // SIRT
+ NULL,
+ };
+
size_t sirt_member_index = 0;
// Push class argument if this method is static
if (is_static) {
+ // Load class object
llvm::Value* class_object_addr =
LoadFromObjectOffset(method_object_addr,
Method::DeclaringClassOffset().Int32Value(),
irb_.getJObjectTy());
gep_index[2] = irb_.getInt32(sirt_member_index++);
+ // Store the class argument to SIRT
llvm::Value* sirt_field_addr = irb_.CreateGEP(shadow_frame_, gep_index);
irb_.CreateStore(class_object_addr, sirt_field_addr);
args.push_back(irb_.CreateBitCast(sirt_field_addr, irb_.getJObjectTy()));
}
+ // Store arguments to SIRT, and push back to args
for (arg_iter = arg_begin; arg_iter != arg_end; ++arg_iter) {
if (arg_iter->getType() == irb_.getJObjectTy()) {
+ // Store the reference type arguments to SIRT
gep_index[2] = irb_.getInt32(sirt_member_index++);
llvm::Value* sirt_field_addr = irb_.CreateGEP(shadow_frame_, gep_index);
irb_.CreateStore(arg_iter, sirt_field_addr);
@@ -199,7 +204,6 @@ CompiledMethod* JniCompiler::Compile() {
irb_.getInt32Ty());
StoreToObjectOffset(jni_env_object_addr,
JNIEnvExt::LocalRefCookieOffset().Int32Value(),
- irb_.getInt32Ty(),
segment_state);
@@ -208,8 +212,9 @@ CompiledMethod* JniCompiler::Compile() {
// Set thread state to kRunnable
- StoreToObjectOffset(thread_object_addr, Thread::StateOffset().Int32Value(),
- irb_.getInt32Ty(), irb_.getInt32(Thread::kRunnable));
+ StoreToObjectOffset(thread_object_addr,
+ Thread::StateOffset().Int32Value(),
+ irb_.getInt32(Thread::kRunnable));
// Get return shorty
DexFile::MethodId const& method_id = dex_file_->GetMethodId(method_idx_);
@@ -220,7 +225,8 @@ CompiledMethod* JniCompiler::Compile() {
if (ret_shorty == 'L') {
// If the return value is reference, it may point to SIRT, we should decode it.
retval = irb_.CreateCall2(irb_.GetRuntime(runtime_support::DecodeJObjectInThread),
- thread_object_addr, retval);
+ thread_object_addr,
+ retval);
}
// env->locals.segment_state = env->local_ref_cookie
@@ -230,12 +236,12 @@ CompiledMethod* JniCompiler::Compile() {
irb_.getInt32Ty());
StoreToObjectOffset(jni_env_object_addr,
JNIEnvExt::SegmentStateOffset().Int32Value(),
- irb_.getInt32Ty(),
local_ref_cookie);
// env->local_ref_cookie = saved_local_ref_cookie
- StoreToObjectOffset(jni_env_object_addr, JNIEnvExt::LocalRefCookieOffset().Int32Value(),
- irb_.getInt32Ty(), saved_local_ref_cookie);
+ StoreToObjectOffset(jni_env_object_addr,
+ JNIEnvExt::LocalRefCookieOffset().Int32Value(),
+ saved_local_ref_cookie);
// Pop the shadow frame
irb_.CreateCall(irb_.GetRuntime(runtime_support::PopShadowFrame));
@@ -305,7 +311,8 @@ llvm::FunctionType* JniCompiler::GetFunctionType(uint32_t method_idx,
return llvm::FunctionType::get(ret_type, args_type, false);
}
-llvm::Value* JniCompiler::LoadFromObjectOffset(llvm::Value* object_addr, int32_t offset,
+llvm::Value* JniCompiler::LoadFromObjectOffset(llvm::Value* object_addr,
+ int32_t offset,
llvm::Type* type) {
// Convert offset to llvm::value
llvm::Value* llvm_offset = irb_.getPtrEquivInt(offset);
@@ -315,14 +322,17 @@ llvm::Value* JniCompiler::LoadFromObjectOffset(llvm::Value* object_addr, int32_t
return irb_.CreateLoad(value_addr);
}
-void JniCompiler::StoreToObjectOffset(llvm::Value* object_addr, int32_t offset,
- llvm::Type* type, llvm::Value* value) {
+void JniCompiler::StoreToObjectOffset(llvm::Value* object_addr,
+ int32_t offset,
+ llvm::Value* new_value) {
// Convert offset to llvm::value
llvm::Value* llvm_offset = irb_.getPtrEquivInt(offset);
// Calculate the value's address
- llvm::Value* value_addr = irb_.CreatePtrDisp(object_addr, llvm_offset, type->getPointerTo());
+ llvm::Value* value_addr = irb_.CreatePtrDisp(object_addr,
+ llvm_offset,
+ new_value->getType()->getPointerTo());
// Store
- irb_.CreateStore(value, value_addr);
+ irb_.CreateStore(new_value, value_addr);
}
} // namespace compiler_llvm
diff --git a/src/compiler_llvm/jni_compiler.h b/src/compiler_llvm/jni_compiler.h
index 98129d1251..a6ddce3897 100644
--- a/src/compiler_llvm/jni_compiler.h
+++ b/src/compiler_llvm/jni_compiler.h
@@ -66,8 +66,7 @@ class JniCompiler {
private:
llvm::Value* LoadFromObjectOffset(llvm::Value* object_addr, int32_t offset, llvm::Type* type);
- void StoreToObjectOffset(llvm::Value* object_addr, int32_t offset,
- llvm::Type* type, llvm::Value* value);
+ void StoreToObjectOffset(llvm::Value* object_addr, int32_t offset, llvm::Value* new_value);
CompilationUnit* cunit_;
Compiler const* compiler_;