diff options
| author | 2013-01-15 17:57:45 -0800 | |
|---|---|---|
| committer | 2013-01-15 17:57:45 -0800 | |
| commit | 79ec6cd9309e8f916a6d80957674c74e1104e7fc (patch) | |
| tree | 09621d97c37af5f66c1d19cf484bb587b9d4fae0 | |
| parent | ec0f83d95e2174c97e93279ffa71642be7e12b60 (diff) | |
| parent | a1ae861c673ab5160a2a7afee2ada806cb61966b (diff) | |
Merge "Change LLVM exception check to check all thread flags." into dalvik-dev
| -rw-r--r-- | src/compiler_llvm/gbc_expander.cc | 26 | ||||
| -rw-r--r-- | src/compiler_llvm/method_compiler.cc | 26 | ||||
| -rw-r--r-- | src/compiler_llvm/runtime_support_builder.cc | 8 |
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)); } |