summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author buzbee <buzbee@google.com> 2013-07-28 00:43:02 -0700
committer Android Git Automerger <android-git-automerger@android.com> 2013-07-28 00:43:02 -0700
commit024a7276735f0cdd4ff5691a12e698cc7c527d5f (patch)
tree4348bf588e7cd427cf91d6bf8001fb3fa8d3b933
parentecde136fb42c38cf9928982605abfcd6de46d86a (diff)
parent64d8f18c94b23cb4ff908304aef4d9f3f5a85f39 (diff)
am 64d8f18c: Merge "Support inline dex data"
* commit '64d8f18c94b23cb4ff908304aef4d9f3f5a85f39': Support inline dex data
-rw-r--r--compiler/dex/mir_graph.cc50
-rw-r--r--runtime/verifier/method_verifier.cc4
2 files changed, 48 insertions, 6 deletions
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index 6b010ed9b3..9af14a47a8 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -605,9 +605,6 @@ void MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_
opcode_count_[static_cast<int>(opcode)]++;
}
- /* Terminate when the data section is seen */
- if (width == 0)
- break;
/* Possible simple method? */
if (live_pattern) {
@@ -626,9 +623,6 @@ void MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_
pattern_pos++;
}
- AppendMIR(cur_block, insn);
-
- code_ptr += width;
int flags = Instruction::FlagsOf(insn->dalvikInsn.opcode);
int df_flags = oat_data_flow_attributes_[insn->dalvikInsn.opcode];
@@ -637,6 +631,50 @@ void MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_
def_count_ += (df_flags & DF_A_WIDE) ? 2 : 1;
}
+ // Check for inline data block signatures
+ if (opcode == Instruction::NOP) {
+ const uint16_t* tmp_code_ptr = code_ptr;
+ int tmp_width = 0;
+ uint16_t raw_instruction = *tmp_code_ptr;
+ bool embedded_data_block = true;
+ if (raw_instruction == 0x0000) {
+ // Could be an aligning nop - see if an embedded data block follows.
+ tmp_code_ptr++;
+ tmp_width++;
+ raw_instruction = *tmp_code_ptr;
+ }
+ if (raw_instruction == Instruction::kSparseSwitchSignature) {
+ tmp_width += (tmp_code_ptr[1] * 4) + 2;
+ } else if (raw_instruction == Instruction::kPackedSwitchSignature) {
+ tmp_width += (tmp_code_ptr[1] * 2) + 4;
+ } else if (raw_instruction == Instruction::kArrayDataSignature) {
+ int element_width = tmp_code_ptr[1];
+ int num_elements = tmp_code_ptr[2] + (tmp_code_ptr[3] << 16);
+ tmp_width += (((num_elements * element_width) + 1) / 2) + 4;
+ } else {
+ // Just a normal nop - process as usual.
+ embedded_data_block = false;
+ AppendMIR(cur_block, insn);
+ }
+ if (embedded_data_block) {
+ width = tmp_width;
+ DCHECK(cur_block->fall_through == NULL);
+ DCHECK(cur_block->taken == NULL);
+ // No fallthrough for this block
+ flags = 0;
+ df_flags = 0;
+ // If there's more code following, make sure there's a basic block to attach it to.
+ if ((code_ptr + width) < code_end) {
+ FindBlock(current_offset_ + width, /* split */ false, /* create */ true,
+ /* immed_pred_block_p */ NULL);
+ }
+ }
+ } else {
+ AppendMIR(cur_block, insn);
+ }
+
+ code_ptr += width;
+
if (flags & Instruction::kBranch) {
cur_block = ProcessCanBranch(cur_block, insn, current_offset_,
width, flags, code_ptr, code_end);
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 1481ad925f..1b8b47e10a 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -557,9 +557,13 @@ bool MethodVerifier::ScanTryCatchBlocks() {
}
const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc);
if (inst->Opcode() != Instruction::MOVE_EXCEPTION) {
+#if 0
+ // FIXME: this did not cause a hard failure w/ the Dalvik verifier, and code exists
+ // in the wild that trips this. Restore the check based on future dex versioning.
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "exception handler doesn't start with move-exception ("
<< dex_pc << ")";
return false;
+#endif
}
insn_flags_[dex_pc].SetBranchTarget();
// Ensure exception types are resolved so that they don't need resolution to be delivered,