summaryrefslogtreecommitdiffstats
path: root/compiler/dex/quick/codegen_util.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/dex/quick/codegen_util.cc')
-rw-r--r--compiler/dex/quick/codegen_util.cc85
1 files changed, 35 insertions, 50 deletions
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index 04113dba81..88a4605a6b 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -557,29 +557,49 @@ void Mir2Lir::InstallSwitchTables() {
LOG(INFO) << "Switch table for offset 0x" << std::hex << bx_offset;
}
if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
- const int32_t* keys = reinterpret_cast<const int32_t*>(&(tab_rec->table[2]));
- for (int elems = 0; elems < tab_rec->table[1]; elems++) {
- int disp = tab_rec->targets[elems]->offset - bx_offset;
+ DCHECK(tab_rec->switch_mir != nullptr);
+ BasicBlock* bb = mir_graph_->GetBasicBlock(tab_rec->switch_mir->bb);
+ DCHECK(bb != nullptr);
+ int elems = 0;
+ for (SuccessorBlockInfo* successor_block_info : bb->successor_blocks) {
+ int key = successor_block_info->key;
+ int target = successor_block_info->block;
+ LIR* boundary_lir = InsertCaseLabel(target, key);
+ DCHECK(boundary_lir != nullptr);
+ int disp = boundary_lir->offset - bx_offset;
+ Push32(code_buffer_, key);
+ Push32(code_buffer_, disp);
if (cu_->verbose) {
LOG(INFO) << " Case[" << elems << "] key: 0x"
- << std::hex << keys[elems] << ", disp: 0x"
+ << std::hex << key << ", disp: 0x"
<< std::hex << disp;
}
- Push32(code_buffer_, keys[elems]);
- Push32(code_buffer_,
- tab_rec->targets[elems]->offset - bx_offset);
+ elems++;
}
+ DCHECK_EQ(elems, tab_rec->table[1]);
} else {
DCHECK_EQ(static_cast<int>(tab_rec->table[0]),
static_cast<int>(Instruction::kPackedSwitchSignature));
- for (int elems = 0; elems < tab_rec->table[1]; elems++) {
- int disp = tab_rec->targets[elems]->offset - bx_offset;
+ DCHECK(tab_rec->switch_mir != nullptr);
+ BasicBlock* bb = mir_graph_->GetBasicBlock(tab_rec->switch_mir->bb);
+ DCHECK(bb != nullptr);
+ int elems = 0;
+ int low_key = s4FromSwitchData(&tab_rec->table[2]);
+ for (SuccessorBlockInfo* successor_block_info : bb->successor_blocks) {
+ int key = successor_block_info->key;
+ DCHECK_EQ(elems + low_key, key);
+ int target = successor_block_info->block;
+ LIR* boundary_lir = InsertCaseLabel(target, key);
+ DCHECK(boundary_lir != nullptr);
+ int disp = boundary_lir->offset - bx_offset;
+ Push32(code_buffer_, disp);
if (cu_->verbose) {
LOG(INFO) << " Case[" << elems << "] disp: 0x"
<< std::hex << disp;
}
- Push32(code_buffer_, tab_rec->targets[elems]->offset - bx_offset);
+ elems++;
}
+ DCHECK_EQ(elems, tab_rec->table[1]);
}
}
}
@@ -830,13 +850,15 @@ int Mir2Lir::AssignFillArrayDataOffset(CodeOffset offset) {
* branch table during the assembly phase. All resource flags
* are set to prevent code motion. KeyVal is just there for debugging.
*/
-LIR* Mir2Lir::InsertCaseLabel(DexOffset vaddr, int keyVal) {
- LIR* boundary_lir = &block_label_list_[mir_graph_->FindBlock(vaddr)->id];
+LIR* Mir2Lir::InsertCaseLabel(uint32_t bbid, int keyVal) {
+ LIR* boundary_lir = &block_label_list_[bbid];
LIR* res = boundary_lir;
if (cu_->verbose) {
// Only pay the expense if we're pretty-printing.
LIR* new_label = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), kArenaAllocLIR));
- new_label->dalvik_offset = vaddr;
+ BasicBlock* bb = mir_graph_->GetBasicBlock(bbid);
+ DCHECK(bb != nullptr);
+ new_label->dalvik_offset = bb->start_offset;
new_label->opcode = kPseudoCaseLabel;
new_label->operands[0] = keyVal;
new_label->flags.fixup = kFixupLabel;
@@ -848,40 +870,6 @@ LIR* Mir2Lir::InsertCaseLabel(DexOffset vaddr, int keyVal) {
return res;
}
-void Mir2Lir::MarkPackedCaseLabels(Mir2Lir::SwitchTable* tab_rec) {
- const uint16_t* table = tab_rec->table;
- DexOffset base_vaddr = tab_rec->vaddr;
- const int32_t *targets = reinterpret_cast<const int32_t*>(&table[4]);
- int entries = table[1];
- int low_key = s4FromSwitchData(&table[2]);
- for (int i = 0; i < entries; i++) {
- tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], i + low_key);
- }
-}
-
-void Mir2Lir::MarkSparseCaseLabels(Mir2Lir::SwitchTable* tab_rec) {
- const uint16_t* table = tab_rec->table;
- DexOffset base_vaddr = tab_rec->vaddr;
- int entries = table[1];
- const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]);
- const int32_t* targets = &keys[entries];
- for (int i = 0; i < entries; i++) {
- tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], keys[i]);
- }
-}
-
-void Mir2Lir::ProcessSwitchTables() {
- for (Mir2Lir::SwitchTable* tab_rec : switch_tables_) {
- if (tab_rec->table[0] == Instruction::kPackedSwitchSignature) {
- MarkPackedCaseLabels(tab_rec);
- } else if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
- MarkSparseCaseLabels(tab_rec);
- } else {
- LOG(FATAL) << "Invalid switch table";
- }
- }
-}
-
void Mir2Lir::DumpSparseSwitchTable(const uint16_t* table) {
/*
* Sparse switch data format:
@@ -1032,9 +1020,6 @@ void Mir2Lir::Materialize() {
/* Method is not empty */
if (first_lir_insn_) {
- // mark the targets of switch statement case labels
- ProcessSwitchTables();
-
/* Convert LIR into machine code. */
AssembleLIR();