diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-09-10 10:23:58 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-09-15 12:43:06 +0100 |
commit | 6fbce029fba3ed5da6c36017754ed408e6bcb632 (patch) | |
tree | 71debbb7c475be1508e14a7986ed69e75e5b0e4c /compiler/optimizing/builder.cc | |
parent | 8accb5ac557598fd40b80214bf87517bc4b7bc41 (diff) | |
download | art-6fbce029fba3ed5da6c36017754ed408e6bcb632.tar.gz art-6fbce029fba3ed5da6c36017754ed408e6bcb632.tar.bz2 art-6fbce029fba3ed5da6c36017754ed408e6bcb632.zip |
Implement suspend checks in new compiler.
For simplicity, they are currently placed on all (dex-level)
back edges, and at method entry.
Change-Id: I6e833e244d559dd788c69727e22fe40aff5b3435
Diffstat (limited to 'compiler/optimizing/builder.cc')
-rw-r--r-- | compiler/optimizing/builder.cc | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index ecd6802ca..71e71f79d 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -138,13 +138,15 @@ static bool CanHandleCodeItem(const DexFile::CodeItem& code_item) { template<typename T> void HGraphBuilder::If_22t(const Instruction& instruction, uint32_t dex_offset) { + int32_t target_offset = instruction.GetTargetOffset(); + PotentiallyAddSuspendCheck(target_offset, dex_offset); HInstruction* first = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); T* comparison = new (arena_) T(first, second); current_block_->AddInstruction(comparison); HInstruction* ifinst = new (arena_) HIf(comparison); current_block_->AddInstruction(ifinst); - HBasicBlock* target = FindBlockStartingAt(dex_offset + instruction.GetTargetOffset()); + HBasicBlock* target = FindBlockStartingAt(dex_offset + target_offset); DCHECK(target != nullptr); current_block_->AddSuccessor(target); target = FindBlockStartingAt(dex_offset + instruction.SizeInCodeUnits()); @@ -155,12 +157,15 @@ void HGraphBuilder::If_22t(const Instruction& instruction, uint32_t dex_offset) template<typename T> void HGraphBuilder::If_21t(const Instruction& instruction, uint32_t dex_offset) { + int32_t target_offset = instruction.GetTargetOffset(); + PotentiallyAddSuspendCheck(target_offset, dex_offset); HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); T* comparison = new (arena_) T(value, GetIntConstant(0)); current_block_->AddInstruction(comparison); HInstruction* ifinst = new (arena_) HIf(comparison); current_block_->AddInstruction(ifinst); - HBasicBlock* target = FindBlockStartingAt(dex_offset + instruction.GetTargetOffset()); + fprintf(stderr, "%d and %d\n", dex_offset, target_offset); + HBasicBlock* target = FindBlockStartingAt(dex_offset + target_offset); DCHECK(target != nullptr); current_block_->AddSuccessor(target); target = FindBlockStartingAt(dex_offset + instruction.SizeInCodeUnits()); @@ -196,6 +201,9 @@ HGraph* HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) { return nullptr; } + // Add the suspend check to the entry block. + entry_block_->AddInstruction(new (arena_) HSuspendCheck(0)); + size_t dex_offset = 0; while (code_ptr < code_end) { // Update the current block if dex_offset starts a new block. @@ -462,7 +470,15 @@ void HGraphBuilder::BuildArrayAccess(const Instruction& instruction, } } -bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_t dex_offset) { +void HGraphBuilder::PotentiallyAddSuspendCheck(int32_t target_offset, uint32_t dex_offset) { + if (target_offset <= 0) { + // Unconditionnally add a suspend check to backward branches. We can remove + // them after we recognize loops in the graph. + current_block_->AddInstruction(new (arena_) HSuspendCheck(dex_offset)); + } +} + +bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32_t dex_offset) { if (current_block_ == nullptr) { return true; // Dead code } @@ -580,7 +596,9 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_ case Instruction::GOTO: case Instruction::GOTO_16: case Instruction::GOTO_32: { - HBasicBlock* target = FindBlockStartingAt(instruction.GetTargetOffset() + dex_offset); + int32_t offset = instruction.GetTargetOffset(); + PotentiallyAddSuspendCheck(offset, dex_offset); + HBasicBlock* target = FindBlockStartingAt(offset + dex_offset); DCHECK(target != nullptr); current_block_->AddInstruction(new (arena_) HGoto()); current_block_->AddSuccessor(target); |