summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler_llvm/art_module.ll4
-rw-r--r--src/compiler_llvm/compilation_unit.cc4
-rw-r--r--src/compiler_llvm/generated/art_module.cc12
-rw-r--r--src/compiler_llvm/ir_builder.h10
-rw-r--r--src/compiler_llvm/jni_compiler.cc30
-rw-r--r--src/compiler_llvm/method_compiler.cc71
-rw-r--r--src/compiler_llvm/runtime_support_builder.cc224
-rw-r--r--src/compiler_llvm/runtime_support_builder.h28
-rw-r--r--src/compiler_llvm/runtime_support_builder_arm.cc60
-rw-r--r--src/compiler_llvm/runtime_support_builder_arm.h10
-rw-r--r--src/compiler_llvm/runtime_support_builder_x86.cc61
-rw-r--r--src/compiler_llvm/runtime_support_builder_x86.h10
-rw-r--r--src/compiler_llvm/runtime_support_func_list.h1
-rw-r--r--src/compiler_llvm/runtime_support_llvm.cc15
-rw-r--r--src/compiler_llvm/runtime_support_llvm.h6
-rw-r--r--src/compiler_llvm/upcall_compiler.cc4
-rw-r--r--src/shadow_frame.h13
-rw-r--r--src/thread.cc12
-rw-r--r--src/thread.h16
19 files changed, 302 insertions, 289 deletions
diff --git a/src/compiler_llvm/art_module.ll b/src/compiler_llvm/art_module.ll
index cebc76c..f831736 100644
--- a/src/compiler_llvm/art_module.ll
+++ b/src/compiler_llvm/art_module.ll
@@ -43,8 +43,8 @@ declare void @art_unlock_object_from_code(%JavaObject*, %JavaObject*)
declare void @art_test_suspend_from_code(%JavaObject*)
-declare %ShadowFrame* @art_push_shadow_frame_from_code(%ShadowFrame*, %JavaObject*, i32)
-declare %ShadowFrame* @art_push_shadow_frame_noinline_from_code(%ShadowFrame*, %JavaObject*, i32)
+declare %ShadowFrame* @art_push_shadow_frame_from_code(%JavaObject*, %ShadowFrame*,
+ %JavaObject*, i32)
declare void @art_pop_shadow_frame_from_code(%ShadowFrame*)
diff --git a/src/compiler_llvm/compilation_unit.cc b/src/compiler_llvm/compilation_unit.cc
index b4bdd5d..266377e 100644
--- a/src/compiler_llvm/compilation_unit.cc
+++ b/src/compiler_llvm/compilation_unit.cc
@@ -142,10 +142,8 @@ class AddSuspendCheckToLoopLatchPass : public llvm::LoopPass {
irb_->SetInsertPoint(bb->getTerminator());
using art::compiler_llvm::runtime_support::TestSuspend;
- using art::compiler_llvm::runtime_support::GetCurrentThread;
llvm::Value* runtime_func = irb_->GetRuntime(TestSuspend);
- llvm::Value* thread_object_addr = irb_->CreateCall(irb_->GetRuntime(GetCurrentThread));
- irb_->CreateCall(runtime_func, thread_object_addr);
+ irb_->CreateCall(runtime_func, irb_->getJNull());
return true;
}
diff --git a/src/compiler_llvm/generated/art_module.cc b/src/compiler_llvm/generated/art_module.cc
index 1f88e8d..2a8100b 100644
--- a/src/compiler_llvm/generated/art_module.cc
+++ b/src/compiler_llvm/generated/art_module.cc
@@ -83,6 +83,7 @@ FunctionType* FuncTy_5 = FunctionType::get(
/*isVarArg=*/false);
std::vector<Type*>FuncTy_6_args;
+FuncTy_6_args.push_back(PointerTy_1);
FuncTy_6_args.push_back(PointerTy_2);
FuncTy_6_args.push_back(PointerTy_1);
FuncTy_6_args.push_back(IntegerType::get(mod->getContext(), 32));
@@ -425,17 +426,6 @@ func_art_push_shadow_frame_from_code->setCallingConv(CallingConv::C);
AttrListPtr func_art_push_shadow_frame_from_code_PAL;
func_art_push_shadow_frame_from_code->setAttributes(func_art_push_shadow_frame_from_code_PAL);
-Function* func_art_push_shadow_frame_noinline_from_code = mod->getFunction("art_push_shadow_frame_noinline_from_code");
-if (!func_art_push_shadow_frame_noinline_from_code) {
-func_art_push_shadow_frame_noinline_from_code = Function::Create(
- /*Type=*/FuncTy_6,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_push_shadow_frame_noinline_from_code", mod); // (external, no body)
-func_art_push_shadow_frame_noinline_from_code->setCallingConv(CallingConv::C);
-}
-AttrListPtr func_art_push_shadow_frame_noinline_from_code_PAL;
-func_art_push_shadow_frame_noinline_from_code->setAttributes(func_art_push_shadow_frame_noinline_from_code_PAL);
-
Function* func_art_pop_shadow_frame_from_code = mod->getFunction("art_pop_shadow_frame_from_code");
if (!func_art_pop_shadow_frame_from_code) {
func_art_pop_shadow_frame_from_code = Function::Create(
diff --git a/src/compiler_llvm/ir_builder.h b/src/compiler_llvm/ir_builder.h
index 46c37f1..f21cfaf 100644
--- a/src/compiler_llvm/ir_builder.h
+++ b/src/compiler_llvm/ir_builder.h
@@ -120,8 +120,8 @@ class IRBuilder : public LLVMIRBuilder {
StoreToObjectOffset(object_addr, offset, new_value, tbaa_.GetMemoryJType(special_ty, j_ty));
}
- void SetTBAACall(llvm::CallInst* call_inst, TBAASpecialType special_ty) {
- call_inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_.GetSpecialType(special_ty));
+ void SetTBAA(llvm::Instruction* inst, TBAASpecialType special_ty) {
+ inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_.GetSpecialType(special_ty));
}
@@ -217,10 +217,16 @@ class IRBuilder : public LLVMIRBuilder {
// Runtime Helper Function
//--------------------------------------------------------------------------
+ RuntimeSupportBuilder& Runtime() {
+ return *runtime_support_;
+ }
+
+ // TODO: Deprecate
llvm::Function* GetRuntime(runtime_support::RuntimeId rt) {
return runtime_support_->GetRuntimeSupportFunction(rt);
}
+ // TODO: Deprecate
void SetRuntimeSupport(RuntimeSupportBuilder* runtime_support) {
// Can only set once. We can't do this on constructor, because RuntimeSupportBuilder needs
// IRBuilder.
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
index e66674c..838c89d 100644
--- a/src/compiler_llvm/jni_compiler.cc
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -109,7 +109,7 @@ CompiledMethod* JniCompiler::Compile() {
}
// Get thread object
- llvm::Value* thread_object_addr = irb_.CreateCall(irb_.GetRuntime(GetCurrentThread));
+ llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
// Shadow stack
llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(sirt_size);
@@ -124,21 +124,18 @@ CompiledMethod* JniCompiler::Compile() {
// Push the shadow frame
llvm::Value* shadow_frame_upcast = irb_.CreateConstGEP2_32(shadow_frame_, 0, 0);
llvm::Value* old_shadow_frame =
- irb_.CreateCall3(irb_.GetRuntime(PushShadowFrame),
- shadow_frame_upcast, method_object_addr, irb_.getInt32(sirt_size));
+ irb_.Runtime().EmitPushShadowFrame(shadow_frame_upcast, method_object_addr, sirt_size);
// Get JNIEnv
llvm::Value* jni_env_object_addr =
- irb_.LoadFromObjectOffset(thread_object_addr,
- Thread::JniEnvOffset().Int32Value(),
- irb_.getJObjectTy(),
- kTBAAJRuntime);
+ irb_.Runtime().EmitLoadFromThreadOffset(Thread::JniEnvOffset().Int32Value(),
+ irb_.getJObjectTy(),
+ kTBAAJRuntime);
// Set thread state to kNative
- irb_.StoreToObjectOffset(thread_object_addr,
- Thread::StateOffset().Int32Value(),
- irb_.getInt32(kNative),
- kTBAARuntimeInfo);
+ irb_.Runtime().EmitStoreToThreadOffset(Thread::StateOffset().Int32Value(),
+ irb_.getInt32(kNative),
+ kTBAARuntimeInfo);
// Get callee code_addr
llvm::Value* code_addr =
@@ -227,13 +224,12 @@ CompiledMethod* JniCompiler::Compile() {
}
// Set thread state to kRunnable
- irb_.StoreToObjectOffset(thread_object_addr,
- Thread::StateOffset().Int32Value(),
- irb_.getInt32(kRunnable),
- kTBAARuntimeInfo);
+ irb_.Runtime().EmitStoreToThreadOffset(Thread::StateOffset().Int32Value(),
+ irb_.getInt32(kRunnable),
+ kTBAARuntimeInfo);
// Do a suspend check
- irb_.CreateCall(irb_.GetRuntime(TestSuspend), thread_object_addr);
+ irb_.Runtime().EmitTestSuspend();
if (return_shorty == 'L') {
// If the return value is reference, it may point to SIRT, we should decode it.
@@ -260,7 +256,7 @@ CompiledMethod* JniCompiler::Compile() {
kTBAARuntimeInfo);
// Pop the shadow frame
- irb_.CreateCall(irb_.GetRuntime(PopShadowFrame), old_shadow_frame);
+ irb_.Runtime().EmitPopShadowFrame(old_shadow_frame);
// Return!
if (return_shorty != 'V') {
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index bdad82b..620ba39 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -214,14 +214,10 @@ void MethodCompiler::EmitStackOverflowCheck() {
frame_address = irb_.CreatePtrToInt(frame_address, irb_.getPtrEquivIntTy());
// Get thread.stack_end_
- llvm::Value* thread_object_addr =
- irb_.CreateCall(irb_.GetRuntime(GetCurrentThread));
-
llvm::Value* stack_end =
- irb_.LoadFromObjectOffset(thread_object_addr,
- Thread::StackEndOffset().Int32Value(),
- irb_.getPtrEquivIntTy(),
- kTBAARuntimeInfo);
+ irb_.Runtime().EmitLoadFromThreadOffset(Thread::StackEndOffset().Int32Value(),
+ irb_.getPtrEquivIntTy(),
+ kTBAARuntimeInfo);
// Check the frame address < thread.stack_end_ ?
llvm::Value* is_stack_overflow = irb_.CreateICmpULT(frame_address, stack_end);
@@ -1263,22 +1259,16 @@ void MethodCompiler::EmitInsn_MoveException(uint32_t dex_pc,
DecodedInstruction dec_insn(insn);
- // Get thread
- llvm::Value* thread_object_addr =
- irb_.CreateCall(irb_.GetRuntime(GetCurrentThread));
-
// Get thread-local exception field address
llvm::Value* exception_object_addr =
- irb_.LoadFromObjectOffset(thread_object_addr,
- Thread::ExceptionOffset().Int32Value(),
- irb_.getJObjectTy(),
- kTBAAJRuntime);
+ irb_.Runtime().EmitLoadFromThreadOffset(Thread::ExceptionOffset().Int32Value(),
+ irb_.getJObjectTy(),
+ kTBAAJRuntime);
// Set thread-local exception field address to NULL
- irb_.StoreToObjectOffset(thread_object_addr,
- Thread::ExceptionOffset().Int32Value(),
- irb_.getJNull(),
- kTBAAJRuntime);
+ irb_.Runtime().EmitStoreToThreadOffset(Thread::ExceptionOffset().Int32Value(),
+ irb_.getJNull(),
+ kTBAAJRuntime);
// Keep the exception object in the Dalvik register
EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, exception_object_addr);
@@ -1464,7 +1454,7 @@ llvm::Value* MethodCompiler::EmitLoadConstantClass(uint32_t dex_pc,
llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
- llvm::Value* thread_object_addr = irb_.CreateCall(irb_.GetRuntime(GetCurrentThread));
+ llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
llvm::Function* runtime_func =
irb_.GetRuntime(InitializeTypeAndVerifyAccess);
@@ -1512,7 +1502,7 @@ llvm::Value* MethodCompiler::EmitLoadConstantClass(uint32_t dex_pc,
llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
- llvm::Value* thread_object_addr = irb_.CreateCall(irb_.GetRuntime(GetCurrentThread));
+ llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
EmitUpdateDexPC(dex_pc);
@@ -1562,7 +1552,7 @@ void MethodCompiler::EmitInsn_MonitorEnter(uint32_t dex_pc,
EmitGuard_NullPointerException(dex_pc, object_addr);
}
- llvm::Value* thread_object_addr = irb_.CreateCall(irb_.GetRuntime(GetCurrentThread));
+ llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
irb_.CreateCall2(irb_.GetRuntime(LockObject), object_addr, thread_object_addr);
@@ -1584,7 +1574,7 @@ void MethodCompiler::EmitInsn_MonitorExit(uint32_t dex_pc,
EmitUpdateDexPC(dex_pc);
- llvm::Value* thread_object_addr = irb_.CreateCall(irb_.GetRuntime(GetCurrentThread));
+ llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
irb_.CreateCall2(irb_.GetRuntime(UnlockObject), object_addr, thread_object_addr);
@@ -1762,7 +1752,7 @@ void MethodCompiler::EmitInsn_NewInstance(uint32_t dex_pc,
llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
- llvm::Value* thread_object_addr = irb_.CreateCall(irb_.GetRuntime(GetCurrentThread));
+ llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
EmitUpdateDexPC(dex_pc);
@@ -1805,7 +1795,7 @@ llvm::Value* MethodCompiler::EmitAllocNewArray(uint32_t dex_pc,
llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
- llvm::Value* thread_object_addr = irb_.CreateCall(irb_.GetRuntime(GetCurrentThread));
+ llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
EmitUpdateDexPC(dex_pc);
@@ -2508,7 +2498,7 @@ llvm::Value* MethodCompiler::EmitLoadStaticStorage(uint32_t dex_pc,
llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
- llvm::Value* thread_object_addr = irb_.CreateCall(irb_.GetRuntime(GetCurrentThread));
+ llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
EmitUpdateDexPC(dex_pc);
@@ -3039,7 +3029,7 @@ EmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx,
llvm::Value* caller_method_object_addr = EmitLoadMethodObjectAddr();
- llvm::Value* thread_object_addr = irb_.CreateCall(irb_.GetRuntime(GetCurrentThread));
+ llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
EmitUpdateDexPC(dex_pc);
@@ -3694,8 +3684,7 @@ void MethodCompiler::EmitGuard_ExceptionLandingPad(uint32_t dex_pc, bool can_ski
return;
}
- llvm::Value* exception_pending =
- irb_.CreateCall(irb_.GetRuntime(IsExceptionPending));
+ llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending();
llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont");
@@ -3715,11 +3704,7 @@ void MethodCompiler::EmitGuard_GarbageCollectionSuspend() {
return;
}
- llvm::Value* runtime_func = irb_.GetRuntime(TestSuspend);
-
- llvm::Value* thread_object_addr = irb_.CreateCall(irb_.GetRuntime(GetCurrentThread));
-
- irb_.CreateCall(runtime_func, thread_object_addr);
+ irb_.Runtime().EmitTestSuspend();
}
@@ -3960,9 +3945,15 @@ void MethodCompiler::EmitPushShadowFrame(bool is_inline) {
llvm::Value* shadow_frame_upcast =
irb_.CreateConstGEP2_32(shadow_frame_, 0, 0);
- llvm::Value* result =
- irb_.CreateCall3(irb_.GetRuntime(is_inline ? PushShadowFrame : PushShadowFrameNoInline),
- shadow_frame_upcast, method_object_addr, irb_.getJInt(shadow_frame_size_));
+ llvm::Value* result;
+ if (is_inline) {
+ result = irb_.Runtime().EmitPushShadowFrame(shadow_frame_upcast, method_object_addr,
+ shadow_frame_size_);
+ } else {
+ DCHECK(shadow_frame_size_ == 0);
+ result = irb_.Runtime().EmitPushShadowFrameNoInline(shadow_frame_upcast, method_object_addr,
+ shadow_frame_size_);
+ }
irb_.CreateStore(result, old_shadow_frame_, kTBAARegister);
}
@@ -3981,14 +3972,12 @@ void MethodCompiler::EmitPopShadowFrame() {
irb_.CreateCondBr(need_pop, bb_pop, bb_cont, kUnlikely);
irb_.SetInsertPoint(bb_pop);
- irb_.CreateCall(irb_.GetRuntime(PopShadowFrame),
- irb_.CreateLoad(old_shadow_frame_, kTBAARegister));
+ irb_.Runtime().EmitPopShadowFrame(irb_.CreateLoad(old_shadow_frame_, kTBAARegister));
irb_.CreateBr(bb_cont);
irb_.SetInsertPoint(bb_cont);
} else {
- irb_.CreateCall(irb_.GetRuntime(PopShadowFrame),
- irb_.CreateLoad(old_shadow_frame_, kTBAARegister));
+ irb_.Runtime().EmitPopShadowFrame(irb_.CreateLoad(old_shadow_frame_, kTBAARegister));
}
}
diff --git a/src/compiler_llvm/runtime_support_builder.cc b/src/compiler_llvm/runtime_support_builder.cc
index 2e86938..b0823d6 100644
--- a/src/compiler_llvm/runtime_support_builder.cc
+++ b/src/compiler_llvm/runtime_support_builder.cc
@@ -45,7 +45,7 @@ RuntimeSupportBuilder::RuntimeSupportBuilder(llvm::LLVMContext& context,
do { \
llvm::Function* fn = module_.getFunction(#NAME); \
DCHECK_NE(fn, (void*)NULL) << "Function not found: " << #NAME; \
- runtime_support_func_decls_[ID] = fn; \
+ runtime_support_func_decls_[runtime_support::ID] = fn; \
} while (0);
#include "runtime_support_func_list.h"
@@ -69,115 +69,120 @@ void RuntimeSupportBuilder::OverrideRuntimeSupportFunction(RuntimeId id, llvm::F
}
}
-void RuntimeSupportBuilder::OptimizeRuntimeSupport() {
- TargetOptimizeRuntimeSupport();
- if (!target_runtime_support_func_[PushShadowFrame]) {
- Function* func = GetRuntimeSupportFunction(PushShadowFrame);
- MakeFunctionInline(func);
- BasicBlock* basic_block = BasicBlock::Create(context_, "entry", func);
- irb_.SetInsertPoint(basic_block);
+/* Thread */
- Function* get_thread = GetRuntimeSupportFunction(GetCurrentThread);
- Value* thread = irb_.CreateCall(get_thread);
- Function::arg_iterator arg_iter = func->arg_begin();
- Value* new_shadow_frame = arg_iter++;
- Value* method_object_addr = arg_iter++;
- Value* shadow_frame_size = arg_iter++;
- Value* old_shadow_frame = irb_.LoadFromObjectOffset(thread,
- Thread::TopShadowFrameOffset().Int32Value(),
- irb_.getArtFrameTy()->getPointerTo(),
- kTBAARuntimeInfo);
- irb_.StoreToObjectOffset(thread,
- Thread::TopShadowFrameOffset().Int32Value(),
- new_shadow_frame,
- kTBAARuntimeInfo);
-
- // Store the method pointer
- irb_.StoreToObjectOffset(new_shadow_frame,
- ShadowFrame::MethodOffset(),
- method_object_addr,
- kTBAAShadowFrame);
-
- // Store the number of the pointer slots
- irb_.StoreToObjectOffset(new_shadow_frame,
- ShadowFrame::NumberOfReferencesOffset(),
- shadow_frame_size,
- kTBAAShadowFrame);
-
- // Store the link to previous shadow frame
- irb_.StoreToObjectOffset(new_shadow_frame,
- ShadowFrame::LinkOffset(),
- old_shadow_frame,
- kTBAAShadowFrame);
-
- irb_.CreateRet(old_shadow_frame);
+llvm::Value* RuntimeSupportBuilder::EmitGetCurrentThread() {
+ Function* func = GetRuntimeSupportFunction(runtime_support::GetCurrentThread);
+ llvm::CallInst* call_inst = irb_.CreateCall(func);
+ call_inst->setOnlyReadsMemory();
+ irb_.SetTBAA(call_inst, kTBAAConstJObject);
+ return call_inst;
+}
- VERIFY_LLVM_FUNCTION(*func);
- }
+llvm::Value* RuntimeSupportBuilder::EmitLoadFromThreadOffset(int64_t offset, llvm::Type* type,
+ TBAASpecialType s_ty) {
+ llvm::Value* thread = EmitGetCurrentThread();
+ return irb_.LoadFromObjectOffset(thread, offset, type, s_ty);
+}
- if (!target_runtime_support_func_[PushShadowFrameNoInline]) {
- Function* func = GetRuntimeSupportFunction(PushShadowFrameNoInline);
+void RuntimeSupportBuilder::EmitStoreToThreadOffset(int64_t offset, llvm::Value* value,
+ TBAASpecialType s_ty) {
+ llvm::Value* thread = EmitGetCurrentThread();
+ irb_.StoreToObjectOffset(thread, offset, value, s_ty);
+}
- func->setLinkage(GlobalValue::PrivateLinkage);
- func->addFnAttr(Attribute::NoInline);
+void RuntimeSupportBuilder::EmitSetCurrentThread(llvm::Value* thread) {
+ Function* func = GetRuntimeSupportFunction(runtime_support::SetCurrentThread);
+ irb_.CreateCall(func, thread);
+}
- BasicBlock* basic_block = BasicBlock::Create(context_, "entry", func);
- irb_.SetInsertPoint(basic_block);
- Function::arg_iterator arg_iter = func->arg_begin();
- Value* new_shadow_frame = arg_iter++;
- Value* method_object_addr = arg_iter++;
- Value* shadow_frame_size = arg_iter++;
+/* ShadowFrame */
+
+llvm::Value* RuntimeSupportBuilder::EmitPushShadowFrame(llvm::Value* new_shadow_frame,
+ llvm::Value* method, uint32_t size) {
+ Value* old_shadow_frame = EmitLoadFromThreadOffset(Thread::TopShadowFrameOffset().Int32Value(),
+ irb_.getArtFrameTy()->getPointerTo(),
+ kTBAARuntimeInfo);
+ EmitStoreToThreadOffset(Thread::TopShadowFrameOffset().Int32Value(),
+ new_shadow_frame,
+ kTBAARuntimeInfo);
+
+ // Store the method pointer
+ irb_.StoreToObjectOffset(new_shadow_frame,
+ ShadowFrame::MethodOffset(),
+ method,
+ kTBAAShadowFrame);
+
+ // Store the number of the pointer slots
+ irb_.StoreToObjectOffset(new_shadow_frame,
+ ShadowFrame::NumberOfReferencesOffset(),
+ irb_.getInt32(size),
+ kTBAAShadowFrame);
+
+ // Store the link to previous shadow frame
+ irb_.StoreToObjectOffset(new_shadow_frame,
+ ShadowFrame::LinkOffset(),
+ old_shadow_frame,
+ kTBAAShadowFrame);
+
+ return old_shadow_frame;
+}
- // Call inline version
- Value* old_shadow_frame =
- irb_.CreateCall3(GetRuntimeSupportFunction(PushShadowFrame),
- new_shadow_frame, method_object_addr, shadow_frame_size);
- irb_.CreateRet(old_shadow_frame);
+llvm::Value*
+RuntimeSupportBuilder::EmitPushShadowFrameNoInline(llvm::Value* new_shadow_frame,
+ llvm::Value* method, uint32_t size) {
+ Function* func = GetRuntimeSupportFunction(runtime_support::PushShadowFrame);
+ llvm::CallInst* call_inst =
+ irb_.CreateCall4(func, EmitGetCurrentThread(), new_shadow_frame, method, irb_.getInt32(size));
+ irb_.SetTBAA(call_inst, kTBAARuntimeInfo);
+ return call_inst;
+}
- VERIFY_LLVM_FUNCTION(*func);
- }
+void RuntimeSupportBuilder::EmitPopShadowFrame(llvm::Value* old_shadow_frame) {
+ // Store old shadow frame to TopShadowFrame
+ EmitStoreToThreadOffset(Thread::TopShadowFrameOffset().Int32Value(),
+ old_shadow_frame,
+ kTBAARuntimeInfo);
+}
- if (!target_runtime_support_func_[PopShadowFrame]) {
- Function* func = GetRuntimeSupportFunction(PopShadowFrame);
- MakeFunctionInline(func);
- BasicBlock* basic_block = BasicBlock::Create(context_, "entry", func);
- irb_.SetInsertPoint(basic_block);
- Function* get_thread = GetRuntimeSupportFunction(GetCurrentThread);
- Value* thread = irb_.CreateCall(get_thread);
- Value* old_shadow_frame = func->arg_begin();
- irb_.StoreToObjectOffset(thread,
- Thread::TopShadowFrameOffset().Int32Value(),
- old_shadow_frame,
- kTBAARuntimeInfo);
- irb_.CreateRetVoid();
+/* Check */
- VERIFY_LLVM_FUNCTION(*func);
- }
+llvm::Value* RuntimeSupportBuilder::EmitIsExceptionPending() {
+ Value* exception = EmitLoadFromThreadOffset(Thread::ExceptionOffset().Int32Value(),
+ irb_.getJObjectTy(),
+ kTBAAJRuntime);
+ // If exception not null
+ return irb_.CreateICmpNE(exception, irb_.getJNull());
+}
- if (!target_runtime_support_func_[IsExceptionPending]) {
- Function* func = GetRuntimeSupportFunction(IsExceptionPending);
- MakeFunctionInline(func);
- BasicBlock* basic_block = BasicBlock::Create(context_, "entry", func);
- irb_.SetInsertPoint(basic_block);
+void RuntimeSupportBuilder::EmitTestSuspend() {
+ Function* slow_func = GetRuntimeSupportFunction(runtime_support::TestSuspend);
+ Value* suspend_count = EmitLoadFromThreadOffset(Thread::SuspendCountOffset().Int32Value(),
+ irb_.getJIntTy(),
+ kTBAARuntimeInfo);
+ Value* is_suspend = irb_.CreateICmpNE(suspend_count, irb_.getJInt(0));
- Function* get_thread = GetRuntimeSupportFunction(GetCurrentThread);
- Value* thread = irb_.CreateCall(get_thread);
- Value* exception = irb_.LoadFromObjectOffset(thread,
- Thread::ExceptionOffset().Int32Value(),
- irb_.getJObjectTy(),
- kTBAAJRuntime);
- Value* is_exception_not_null = irb_.CreateICmpNE(exception, irb_.getJNull());
- irb_.CreateRet(is_exception_not_null);
+ llvm::Function* parent_func = irb_.GetInsertBlock()->getParent();
+ BasicBlock* basic_block_suspend = BasicBlock::Create(context_, "suspend", parent_func);
+ BasicBlock* basic_block_cont = BasicBlock::Create(context_, "suspend_cont", parent_func);
+ irb_.CreateCondBr(is_suspend, basic_block_suspend, basic_block_cont, kUnlikely);
- VERIFY_LLVM_FUNCTION(*func);
- }
+ irb_.SetInsertPoint(basic_block_suspend);
+ CallInst* call_inst = irb_.CreateCall(slow_func, EmitGetCurrentThread());
+ irb_.SetTBAA(call_inst, kTBAARuntimeInfo);
+ irb_.CreateBr(basic_block_cont);
+
+ irb_.SetInsertPoint(basic_block_cont);
+}
- if (!target_runtime_support_func_[TestSuspend]) {
- Function* slow_func = GetRuntimeSupportFunction(TestSuspend);
+void RuntimeSupportBuilder::OptimizeRuntimeSupport() {
+ // TODO: Remove this after we remove suspend loop pass.
+ if (!target_runtime_support_func_[runtime_support::TestSuspend]) {
+ Function* slow_func = GetRuntimeSupportFunction(runtime_support::TestSuspend);
Function* func = Function::Create(slow_func->getFunctionType(),
GlobalValue::LinkOnceODRLinkage,
"test_suspend_fast",
@@ -186,29 +191,11 @@ void RuntimeSupportBuilder::OptimizeRuntimeSupport() {
BasicBlock* basic_block = BasicBlock::Create(context_, "entry", func);
irb_.SetInsertPoint(basic_block);
- Value* thread = func->arg_begin();
- llvm::LoadInst* suspend_count =
- irb_.LoadFromObjectOffset(thread,
- Thread::SuspendCountOffset().Int32Value(),
- irb_.getJIntTy(),
- kTBAARuntimeInfo);
- suspend_count->setAlignment(4U);
- suspend_count->setAtomic(Unordered, CrossThread);
- Value* is_suspend = irb_.CreateICmpNE(suspend_count, irb_.getJInt(0));
-
- BasicBlock* basic_block_suspend = BasicBlock::Create(context_, "suspend", func);
- BasicBlock* basic_block_else = BasicBlock::Create(context_, "else", func);
- irb_.CreateCondBr(is_suspend, basic_block_suspend, basic_block_else, kUnlikely);
-
- irb_.SetInsertPoint(basic_block_suspend);
- CallInst* call_inst = irb_.CreateCall(slow_func, thread);
- irb_.SetTBAACall(call_inst, kTBAARuntimeInfo);
- irb_.CreateBr(basic_block_else);
-
- irb_.SetInsertPoint(basic_block_else);
+ EmitTestSuspend();
+
irb_.CreateRetVoid();
- OverrideRuntimeSupportFunction(TestSuspend, func);
+ OverrideRuntimeSupportFunction(runtime_support::TestSuspend, func);
VERIFY_LLVM_FUNCTION(*func);
}
@@ -233,12 +220,9 @@ void RuntimeSupportBuilder::OptimizeRuntimeSupport() {
irb_.CreateRetVoid();
irb_.SetInsertPoint(block_mark_gc_card);
- Function* get_thread = GetRuntimeSupportFunction(GetCurrentThread);
- Value* thread = irb_.CreateCall(get_thread);
- Value* card_table = irb_.LoadFromObjectOffset(thread,
- Thread::CardTableOffset().Int32Value(),
- irb_.getInt8Ty()->getPointerTo(),
- kTBAAConstJObject);
+ Value* card_table = EmitLoadFromThreadOffset(Thread::CardTableOffset().Int32Value(),
+ irb_.getInt8Ty()->getPointerTo(),
+ kTBAAConstJObject);
Value* target_addr_int = irb_.CreatePtrToInt(target_addr, irb_.getPtrEquivIntTy());
Value* card_no = irb_.CreateLShr(target_addr_int, irb_.getPtrEquivInt(GC_CARD_SHIFT));
Value* card_table_entry = irb_.CreateGEP(card_table, card_no);
diff --git a/src/compiler_llvm/runtime_support_builder.h b/src/compiler_llvm/runtime_support_builder.h
index 422285c..89cf30a 100644
--- a/src/compiler_llvm/runtime_support_builder.h
+++ b/src/compiler_llvm/runtime_support_builder.h
@@ -17,13 +17,18 @@
#ifndef ART_SRC_COMPILER_LLVM_RUNTIME_SUPPORT_BUILDER_H_
#define ART_SRC_COMPILER_LLVM_RUNTIME_SUPPORT_BUILDER_H_
+#include "backend_types.h"
#include "logging.h"
#include "runtime_support_func.h"
+#include <stdint.h>
+
namespace llvm {
class LLVMContext;
class Module;
class Function;
+ class Type;
+ class Value;
}
namespace art {
@@ -36,6 +41,25 @@ class RuntimeSupportBuilder {
public:
RuntimeSupportBuilder(llvm::LLVMContext& context, llvm::Module& module, IRBuilder& irb);
+ /* Thread */
+ virtual llvm::Value* EmitGetCurrentThread();
+ virtual llvm::Value* EmitLoadFromThreadOffset(int64_t offset, llvm::Type* type,
+ TBAASpecialType s_ty);
+ virtual void EmitStoreToThreadOffset(int64_t offset, llvm::Value* value,
+ TBAASpecialType s_ty);
+ virtual void EmitSetCurrentThread(llvm::Value* thread);
+
+ /* ShadowFrame */
+ virtual llvm::Value* EmitPushShadowFrame(llvm::Value* new_shadow_frame,
+ llvm::Value* method, uint32_t size);
+ virtual llvm::Value* EmitPushShadowFrameNoInline(llvm::Value* new_shadow_frame,
+ llvm::Value* method, uint32_t size);
+ virtual void EmitPopShadowFrame(llvm::Value* old_shadow_frame);
+
+ /* Check */
+ virtual llvm::Value* EmitIsExceptionPending();
+ virtual void EmitTestSuspend();
+
llvm::Function* GetRuntimeSupportFunction(runtime_support::RuntimeId id) {
if (id >= 0 && id < runtime_support::MAX_ID) {
return runtime_support_func_decls_[id];
@@ -56,10 +80,6 @@ class RuntimeSupportBuilder {
void OverrideRuntimeSupportFunction(runtime_support::RuntimeId id, llvm::Function* function);
- private:
- // Target can override this function to make some runtime support more efficient.
- virtual void TargetOptimizeRuntimeSupport() {}
-
protected:
llvm::LLVMContext& context_;
diff --git a/src/compiler_llvm/runtime_support_builder_arm.cc b/src/compiler_llvm/runtime_support_builder_arm.cc
index 6d5c1e7..a180520 100644
--- a/src/compiler_llvm/runtime_support_builder_arm.cc
+++ b/src/compiler_llvm/runtime_support_builder_arm.cc
@@ -33,37 +33,43 @@ using namespace llvm;
namespace art {
namespace compiler_llvm {
-using namespace runtime_support;
+llvm::Value* RuntimeSupportBuilderARM::EmitGetCurrentThread() {
+ Function* ori_func = GetRuntimeSupportFunction(runtime_support::GetCurrentThread);
+ InlineAsm* func = InlineAsm::get(ori_func->getFunctionType(), "mov $0, r9", "=r", false);
+ CallInst* thread = irb_.CreateCall(func);
+ thread->setDoesNotAccessMemory();
+ irb_.SetTBAA(thread, kTBAAConstJObject);
+ return thread;
+}
-void RuntimeSupportBuilderARM::TargetOptimizeRuntimeSupport() {
- {
- Function* func = GetRuntimeSupportFunction(GetCurrentThread);
- MakeFunctionInline(func);
- BasicBlock* basic_block = BasicBlock::Create(context_, "entry", func);
- irb_.SetInsertPoint(basic_block);
-
- InlineAsm* get_r9 = InlineAsm::get(func->getFunctionType(), "mov $0, r9", "=r", false);
- CallInst* r9 = irb_.CreateCall(get_r9);
- r9->setOnlyReadsMemory();
- irb_.CreateRet(r9);
-
- VERIFY_LLVM_FUNCTION(*func);
- }
-
- {
- Function* func = GetRuntimeSupportFunction(SetCurrentThread);
- MakeFunctionInline(func);
- BasicBlock* basic_block = BasicBlock::Create(context_, "entry", func);
- irb_.SetInsertPoint(basic_block);
+llvm::Value* RuntimeSupportBuilderARM::EmitLoadFromThreadOffset(int64_t offset, llvm::Type* type,
+ TBAASpecialType s_ty) {
+ FunctionType* func_ty = FunctionType::get(/*Result=*/type,
+ /*isVarArg=*/false);
+ std::string inline_asm(StringPrintf("ldr $0, [r9, #%d]", static_cast<int>(offset)));
+ InlineAsm* func = InlineAsm::get(func_ty, inline_asm, "=r", true);
+ CallInst* result = irb_.CreateCall(func);
+ result->setOnlyReadsMemory();
+ irb_.SetTBAA(result, s_ty);
+ return result;
+}
- InlineAsm* set_r9 = InlineAsm::get(func->getFunctionType(), "mov r9, $0", "r", true);
- Value* thread = func->arg_begin();
- irb_.CreateCall(set_r9, thread);
- irb_.CreateRetVoid();
+void RuntimeSupportBuilderARM::EmitStoreToThreadOffset(int64_t offset, llvm::Value* value,
+ TBAASpecialType s_ty) {
+ FunctionType* func_ty = FunctionType::get(/*Result=*/Type::getVoidTy(context_),
+ /*Params=*/value->getType(),
+ /*isVarArg=*/false);
+ std::string inline_asm(StringPrintf("str $0, [r9, #%d]", static_cast<int>(offset)));
+ InlineAsm* func = InlineAsm::get(func_ty, inline_asm, "r", true);
+ CallInst* call_inst = irb_.CreateCall(func, value);
+ irb_.SetTBAA(call_inst, s_ty);
+}
- VERIFY_LLVM_FUNCTION(*func);
- }
+void RuntimeSupportBuilderARM::EmitSetCurrentThread(llvm::Value* thread) {
+ Function* ori_func = GetRuntimeSupportFunction(runtime_support::SetCurrentThread);
+ InlineAsm* func = InlineAsm::get(ori_func->getFunctionType(), "mov r9, $0", "r", true);
+ irb_.CreateCall(func, thread);
}
diff --git a/src/compiler_llvm/runtime_support_builder_arm.h b/src/compiler_llvm/runtime_support_builder_arm.h
index e179366..bf8a589 100644
--- a/src/compiler_llvm/runtime_support_builder_arm.h
+++ b/src/compiler_llvm/runtime_support_builder_arm.h
@@ -26,8 +26,14 @@ class RuntimeSupportBuilderARM : public RuntimeSupportBuilder {
public:
RuntimeSupportBuilderARM(llvm::LLVMContext& context, llvm::Module& module, IRBuilder& irb)
: RuntimeSupportBuilder(context, module, irb) {}
- private:
- virtual void TargetOptimizeRuntimeSupport();
+
+ /* Thread */
+ virtual llvm::Value* EmitGetCurrentThread();
+ virtual llvm::Value* EmitLoadFromThreadOffset(int64_t offset, llvm::Type* type,
+ TBAASpecialType s_ty);
+ virtual void EmitStoreToThreadOffset(int64_t offset, llvm::Value* value,
+ TBAASpecialType s_ty);
+ virtual void EmitSetCurrentThread(llvm::Value* thread);
};
} // namespace compiler_llvm
diff --git a/src/compiler_llvm/runtime_support_builder_x86.cc b/src/compiler_llvm/runtime_support_builder_x86.cc
index c83c22d..1a0a78a 100644
--- a/src/compiler_llvm/runtime_support_builder_x86.cc
+++ b/src/compiler_llvm/runtime_support_builder_x86.cc
@@ -17,6 +17,7 @@
#include "runtime_support_builder_x86.h"
#include "ir_builder.h"
+#include "stringprintf.h"
#include "thread.h"
#include "utils_llvm.h"
@@ -33,38 +34,42 @@ using namespace llvm;
namespace art {
namespace compiler_llvm {
-using namespace runtime_support;
+llvm::Value* RuntimeSupportBuilderX86::EmitGetCurrentThread() {
+ Function* ori_func = GetRuntimeSupportFunction(runtime_support::GetCurrentThread);
+ std::string inline_asm(StringPrintf("movl %%fs:%d, $0", Thread::SelfOffset().Int32Value()));
+ InlineAsm* func = InlineAsm::get(ori_func->getFunctionType(), inline_asm, "=r", false);
+ CallInst* thread = irb_.CreateCall(func);
+ thread->setDoesNotAccessMemory();
+ irb_.SetTBAA(thread, kTBAAConstJObject);
+ return thread;
+}
-void RuntimeSupportBuilderX86::TargetOptimizeRuntimeSupport() {
- {
- Function* func = GetRuntimeSupportFunction(GetCurrentThread);
- MakeFunctionInline(func);
- BasicBlock* basic_block = BasicBlock::Create(context_, "entry", func);
- irb_.SetInsertPoint(basic_block);
-
- std::vector<Type*> func_ty_args;
- func_ty_args.push_back(irb_.getPtrEquivIntTy());
- FunctionType* func_ty = FunctionType::get(/*Result=*/irb_.getJObjectTy(),
- /*Params=*/func_ty_args,
- /*isVarArg=*/false);
- InlineAsm* get_fp = InlineAsm::get(func_ty, "movl %fs:($1), $0", "=r,r", false);
- CallInst* fp = irb_.CreateCall(get_fp, irb_.getPtrEquivInt(Thread::SelfOffset().Int32Value()));
- fp->setDoesNotAccessMemory();
- irb_.CreateRet(fp);
-
- VERIFY_LLVM_FUNCTION(*func);
- }
+llvm::Value* RuntimeSupportBuilderX86::EmitLoadFromThreadOffset(int64_t offset, llvm::Type* type,
+ TBAASpecialType s_ty) {
+ FunctionType* func_ty = FunctionType::get(/*Result=*/type,
+ /*isVarArg=*/false);
+ std::string inline_asm(StringPrintf("movl %%fs:%d, $0", static_cast<int>(offset)));
+ InlineAsm* func = InlineAsm::get(func_ty, inline_asm, "=r", true);
+ CallInst* result = irb_.CreateCall(func);
+ result->setOnlyReadsMemory();
+ irb_.SetTBAA(result, s_ty);
+ return result;
+}
- {
- Function* func = GetRuntimeSupportFunction(SetCurrentThread);
- MakeFunctionInline(func);
- BasicBlock* basic_block = BasicBlock::Create(context_, "entry", func);
- irb_.SetInsertPoint(basic_block);
- irb_.CreateRetVoid();
+void RuntimeSupportBuilderX86::EmitStoreToThreadOffset(int64_t offset, llvm::Value* value,
+ TBAASpecialType s_ty) {
+ FunctionType* func_ty = FunctionType::get(/*Result=*/Type::getVoidTy(context_),
+ /*Params=*/value->getType(),
+ /*isVarArg=*/false);
+ std::string inline_asm(StringPrintf("movl $0, %%fs:%d", static_cast<int>(offset)));
+ InlineAsm* func = InlineAsm::get(func_ty, inline_asm, "r", true);
+ CallInst* call_inst = irb_.CreateCall(func, value);
+ irb_.SetTBAA(call_inst, s_ty);
+}
- VERIFY_LLVM_FUNCTION(*func);
- }
+void RuntimeSupportBuilderX86::EmitSetCurrentThread(llvm::Value*) {
+ /* Nothing to be done. */
}
diff --git a/src/compiler_llvm/runtime_support_builder_x86.h b/src/compiler_llvm/runtime_support_builder_x86.h
index 37de81b..ee5d0a3 100644
--- a/src/compiler_llvm/runtime_support_builder_x86.h
+++ b/src/compiler_llvm/runtime_support_builder_x86.h
@@ -26,8 +26,14 @@ class RuntimeSupportBuilderX86 : public RuntimeSupportBuilder {
public:
RuntimeSupportBuilderX86(llvm::LLVMContext& context, llvm::Module& module, IRBuilder& irb)
: RuntimeSupportBuilder(context, module, irb) {}
- private:
- virtual void TargetOptimizeRuntimeSupport();
+
+ /* Thread */
+ virtual llvm::Value* EmitGetCurrentThread();
+ virtual llvm::Value* EmitLoadFromThreadOffset(int64_t offset, llvm::Type* type,
+ TBAASpecialType s_ty);
+ virtual void EmitStoreToThreadOffset(int64_t offset, llvm::Value* value,
+ TBAASpecialType s_ty);
+ virtual void EmitSetCurrentThread(llvm::Value* thread);
};
} // namespace compiler_llvm
diff --git a/src/compiler_llvm/runtime_support_func_list.h b/src/compiler_llvm/runtime_support_func_list.h
index 74af5da..62729c6 100644
--- a/src/compiler_llvm/runtime_support_func_list.h
+++ b/src/compiler_llvm/runtime_support_func_list.h
@@ -20,7 +20,6 @@
V(GetCurrentThread, art_get_current_thread_from_code) \
V(SetCurrentThread, art_set_current_thread_from_code) \
V(PushShadowFrame, art_push_shadow_frame_from_code) \
- V(PushShadowFrameNoInline, art_push_shadow_frame_noinline_from_code) \
V(PopShadowFrame, art_pop_shadow_frame_from_code) \
V(TestSuspend, art_test_suspend_from_code) \
V(ThrowException, art_throw_exception_from_code) \
diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc
index 08e5921..578f84e 100644
--- a/src/compiler_llvm/runtime_support_llvm.cc
+++ b/src/compiler_llvm/runtime_support_llvm.cc
@@ -80,15 +80,12 @@ void art_test_suspend_from_code(Thread* thread) {
Runtime::Current()->GetThreadList()->FullSuspendCheck(thread);
}
-void* art_push_shadow_frame_from_code(void* new_shadow_frame, Object* method, uint32_t size) {
- LOG(FATAL) << "Implemented by IRBuilder.";
- return NULL;
-}
-
-void* art_push_shadow_frame_noinline_from_code(void* new_shadow_frame,
- Object* method, uint32_t size) {
- LOG(FATAL) << "Implemented by IRBuilder.";
- return NULL;
+ShadowFrame* art_push_shadow_frame_from_code(Thread* thread, ShadowFrame* new_shadow_frame,
+ Method* method, uint32_t size) {
+ ShadowFrame* old_frame = thread->PushShadowFrame(new_shadow_frame);
+ new_shadow_frame->SetMethod(method);
+ new_shadow_frame->SetNumberOfReferences(size);
+ return old_frame;
}
void art_pop_shadow_frame_from_code(void*) {
diff --git a/src/compiler_llvm/runtime_support_llvm.h b/src/compiler_llvm/runtime_support_llvm.h
index 5647c54..bca9528 100644
--- a/src/compiler_llvm/runtime_support_llvm.h
+++ b/src/compiler_llvm/runtime_support_llvm.h
@@ -36,10 +36,8 @@ class Object;
// Thread
//----------------------------------------------------------------------------
-void* art_push_shadow_frame_from_code(void* new_shadow_frame, Object* method, uint32_t size);
-
-void* art_push_shadow_frame_noinline_from_code(void* new_shadow_frame,
- Object* method, uint32_t size);
+ShadowFrame* art_push_shadow_frame_from_code(Thread* thread, ShadowFrame* new_shadow_frame,
+ Method* method, uint32_t size);
void art_pop_shadow_frame_from_code(void*);
diff --git a/src/compiler_llvm/upcall_compiler.cc b/src/compiler_llvm/upcall_compiler.cc
index 37dc981..0f3a92e 100644
--- a/src/compiler_llvm/upcall_compiler.cc
+++ b/src/compiler_llvm/upcall_compiler.cc
@@ -91,7 +91,7 @@ CompiledInvokeStub* UpcallCompiler::CreateStub(bool is_static,
llvm::Value* retval_addr = arg_iter++;
// Setup thread pointer
- irb_.CreateCall(irb_.GetRuntime(SetCurrentThread), thread_object_addr);
+ irb_.Runtime().EmitSetCurrentThread(thread_object_addr);
// Accurate function type
llvm::Type* accurate_ret_type = irb_.getJType(shorty[0], kAccurate);
@@ -158,7 +158,7 @@ CompiledInvokeStub* UpcallCompiler::CreateStub(bool is_static,
llvm::Value* code_addr = irb_.CreatePointerCast(result, accurate_func_type->getPointerTo());
// Exception unwind.
- llvm::Value* exception_pending = irb_.CreateCall(irb_.GetRuntime(IsExceptionPending));
+ llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending();
llvm::BasicBlock* block_unwind = llvm::BasicBlock::Create(*context_, "exception_unwind", func);
llvm::BasicBlock* block_cont = llvm::BasicBlock::Create(*context_, "cont", func);
irb_.CreateCondBr(exception_pending, block_unwind, block_cont);
diff --git a/src/shadow_frame.h b/src/shadow_frame.h
index b1ec81f..c4a633f 100644
--- a/src/shadow_frame.h
+++ b/src/shadow_frame.h
@@ -32,11 +32,19 @@ class ShadowFrame {
return number_of_references_;
}
+ void SetNumberOfReferences(uint32_t number_of_references) {
+ number_of_references_ = number_of_references;
+ }
+
// Caller dex pc
uint32_t GetDexPC() const {
return dex_pc_;
}
+ void SetDexPC(uint32_t dex_pc) {
+ dex_pc_ = dex_pc;
+ }
+
// Link to previous shadow frame or NULL
ShadowFrame* GetLink() const {
return link_;
@@ -62,6 +70,11 @@ class ShadowFrame {
return method_;
}
+ void SetMethod(Method* method) {
+ DCHECK_NE(method, static_cast<void*>(NULL));
+ method_ = method;
+ }
+
bool Contains(Object** shadow_frame_entry) const {
// A ShadowFrame should at least contain a reference. Even if a
// native method has no argument, we put jobject or jclass as a
diff --git a/src/thread.cc b/src/thread.cc
index ed6c80f..51b8e31 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -1182,18 +1182,6 @@ static uintptr_t DemanglePc(uintptr_t pc) {
return pc;
}
-void Thread::PushShadowFrame(ShadowFrame* frame) {
- frame->SetLink(top_shadow_frame_);
- top_shadow_frame_ = frame;
-}
-
-ShadowFrame* Thread::PopShadowFrame() {
- CHECK(top_shadow_frame_ != NULL);
- ShadowFrame* frame = top_shadow_frame_;
- top_shadow_frame_ = frame->GetLink();
- return frame;
-}
-
void Thread::PushSirt(StackIndirectReferenceTable* sirt) {
sirt->SetLink(top_sirt_);
top_sirt_ = sirt;
diff --git a/src/thread.h b/src/thread.h
index 9ebe00c..f51b581 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -35,6 +35,7 @@
#include "oat/runtime/oat_support_entrypoints.h"
#include "offsets.h"
#include "runtime_stats.h"
+#include "shadow_frame.h"
#include "stack.h"
#include "trace.h"
#include "UniquePtr.h"
@@ -436,8 +437,19 @@ class PACKED Thread {
return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_pc_));
}
- void PushShadowFrame(ShadowFrame* frame);
- ShadowFrame* PopShadowFrame();
+ ShadowFrame* PushShadowFrame(ShadowFrame* frame) {
+ ShadowFrame* old_frame = top_shadow_frame_;
+ top_shadow_frame_ = frame;
+ frame->SetLink(old_frame);
+ return old_frame;
+ }
+
+ ShadowFrame* PopShadowFrame() {
+ CHECK(top_shadow_frame_ != NULL);
+ ShadowFrame* frame = top_shadow_frame_;
+ top_shadow_frame_ = frame->GetLink();
+ return frame;
+ }
static ThreadOffset TopShadowFrameOffset() {
return ThreadOffset(OFFSETOF_MEMBER(Thread, top_shadow_frame_));