summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author jeffhao <jeffhao@google.com> 2013-01-15 17:57:45 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2013-01-15 17:57:45 -0800
commit79ec6cd9309e8f916a6d80957674c74e1104e7fc (patch)
tree09621d97c37af5f66c1d19cf484bb587b9d4fae0
parentec0f83d95e2174c97e93279ffa71642be7e12b60 (diff)
parenta1ae861c673ab5160a2a7afee2ada806cb61966b (diff)
Merge "Change LLVM exception check to check all thread flags." into dalvik-dev
-rw-r--r--src/compiler_llvm/gbc_expander.cc26
-rw-r--r--src/compiler_llvm/method_compiler.cc26
-rw-r--r--src/compiler_llvm/runtime_support_builder.cc8
3 files changed, 48 insertions, 12 deletions
diff --git a/src/compiler_llvm/gbc_expander.cc b/src/compiler_llvm/gbc_expander.cc
index c285c0bb97..42a87a3556 100644
--- a/src/compiler_llvm/gbc_expander.cc
+++ b/src/compiler_llvm/gbc_expander.cc
@@ -2660,18 +2660,36 @@ void GBCExpanderPass::EmitBranchExceptionLandingPad(uint32_t dex_pc) {
}
void GBCExpanderPass::EmitGuard_ExceptionLandingPad(uint32_t dex_pc) {
- llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending();
-
llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont");
+ llvm::BasicBlock* block_flags = CreateBasicBlockWithDexPC(dex_pc, "flags");
+ llvm::BasicBlock* block_suspend = CreateBasicBlockWithDexPC(dex_pc, "suspend");
+
+ llvm::Value* flags =
+ irb_.Runtime().EmitLoadFromThreadOffset(art::Thread::ThreadFlagsOffset().Int32Value(),
+ irb_.getInt16Ty(),
+ kTBAARuntimeInfo);
+ llvm::Value* flags_set = irb_.CreateICmpNE(flags, irb_.getInt16(0));
+ irb_.CreateCondBr(flags_set, block_flags, block_cont, kUnlikely);
+
+ irb_.SetInsertPoint(block_flags);
+ llvm::Value* exception_pending = irb_.CreateAnd(flags, irb_.getInt16(art::kExceptionPending));
+ llvm::Value* exception_set = irb_.CreateICmpNE(exception_pending, irb_.getInt16(0));
if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) {
landing_pad_phi_mapping_[lpad].push_back(std::make_pair(current_bb_->getUniquePredecessor(),
irb_.GetInsertBlock()));
- irb_.CreateCondBr(exception_pending, lpad, block_cont, kUnlikely);
+ irb_.CreateCondBr(exception_set, lpad, block_suspend, kLikely);
} else {
- irb_.CreateCondBr(exception_pending, GetUnwindBasicBlock(), block_cont, kUnlikely);
+ irb_.CreateCondBr(exception_set, GetUnwindBasicBlock(), block_suspend, kLikely);
}
+ irb_.SetInsertPoint(block_suspend);
+ if (dex_pc != art::DexFile::kDexNoIndex) {
+ EmitUpdateDexPC(dex_pc);
+ }
+ irb_.Runtime().EmitTestSuspend();
+ irb_.CreateBr(block_cont);
+
irb_.SetInsertPoint(block_cont);
}
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index ccec7e96ec..7ab11f5bd5 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -3540,16 +3540,34 @@ void MethodCompiler::EmitGuard_ExceptionLandingPad(uint32_t dex_pc, bool can_ski
return;
}
- llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending();
-
llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont");
+ llvm::BasicBlock* block_flags = CreateBasicBlockWithDexPC(dex_pc, "flags");
+ llvm::BasicBlock* block_suspend = CreateBasicBlockWithDexPC(dex_pc, "suspend");
+
+ llvm::Value* flags =
+ irb_.Runtime().EmitLoadFromThreadOffset(art::Thread::ThreadFlagsOffset().Int32Value(),
+ irb_.getInt16Ty(),
+ kTBAARuntimeInfo);
+ llvm::Value* flags_set = irb_.CreateICmpNE(flags, irb_.getInt16(0));
+ irb_.CreateCondBr(flags_set, block_flags, block_cont, kUnlikely);
+
+ irb_.SetInsertPoint(block_flags);
+ llvm::Value* exception_pending = irb_.CreateAnd(flags, irb_.getInt16(art::kExceptionPending));
+ llvm::Value* exception_set = irb_.CreateICmpNE(exception_pending, irb_.getInt16(0));
if (lpad) {
- irb_.CreateCondBr(exception_pending, lpad, block_cont, kUnlikely);
+ irb_.CreateCondBr(exception_set, lpad, block_suspend, kLikely);
} else {
- irb_.CreateCondBr(exception_pending, GetUnwindBasicBlock(), block_cont, kUnlikely);
+ irb_.CreateCondBr(exception_set, GetUnwindBasicBlock(), block_suspend, kLikely);
}
+ irb_.SetInsertPoint(block_suspend);
+ if (dex_pc != art::DexFile::kDexNoIndex) {
+ EmitUpdateDexPC(dex_pc);
+ }
+ irb_.Runtime().EmitTestSuspend();
+ irb_.CreateBr(block_cont);
+
irb_.SetInsertPoint(block_cont);
}
diff --git a/src/compiler_llvm/runtime_support_builder.cc b/src/compiler_llvm/runtime_support_builder.cc
index 9513d4a1ae..28ef0d3d3e 100644
--- a/src/compiler_llvm/runtime_support_builder.cc
+++ b/src/compiler_llvm/runtime_support_builder.cc
@@ -147,11 +147,11 @@ llvm::Value* RuntimeSupportBuilder::EmitGetAndClearException() {
}
llvm::Value* RuntimeSupportBuilder::EmitIsExceptionPending() {
- Value* state_and_flags = EmitLoadFromThreadOffset(Thread::ThreadFlagsOffset().Int32Value(),
- irb_.getInt16Ty(),
- kTBAARuntimeInfo);
+ Value* flags = EmitLoadFromThreadOffset(Thread::ThreadFlagsOffset().Int32Value(),
+ irb_.getInt16Ty(),
+ kTBAARuntimeInfo);
// Mask exception pending status and return true if non-zero.
- Value* exception_pending = irb_.CreateAnd(state_and_flags, irb_.getInt16(kExceptionPending));
+ Value* exception_pending = irb_.CreateAnd(flags, irb_.getInt16(kExceptionPending));
return irb_.CreateICmpNE(exception_pending, irb_.getInt16(0));
}