/** * The callee contains a *get/put instruction to an unknown field. * Given the caller may not be in the same hierarchy/package we cannot inline * it unless we make the field public. * But we need to make all fields public across the hierarchy and for fields * we don't know we have no idea whether the field was public or not anyway. */ bool MultiMethodInliner::unknown_field(DexInstruction* insn, DexMethod* context) { if (is_ifield_op(insn->opcode()) || is_sfield_op(insn->opcode())) { auto fop = static_cast<DexOpcodeField*>(insn); auto field = fop->field(); field = resolve_field(field, is_sfield_op(insn->opcode()) ? FieldSearch::Static : FieldSearch::Instance); if (field == nullptr) { info.escaped_field++; return true; } if (!field->is_concrete() && !is_public(field)) { info.non_pub_field++; return true; } } return false; }
void MethodBlock::ifield_op(DexOpcode opcode, DexField* field, Location obj, Location& src_or_dst) { always_assert(is_ifield_op(opcode)); if (is_iget(opcode)) { auto iget = new DexOpcodeField(opcode, field); iget->set_dest(reg_num(src_or_dst)); src_or_dst.type = field->get_class(); iget->set_src(0, reg_num(obj)); push_instruction(iget); } else { auto iput = new DexOpcodeField(opcode, field); iput->set_src(0, reg_num(src_or_dst)); iput->set_src(1, reg_num(obj)); push_instruction(iput); } }
void MethodBlock::ifield_op(IROpcode opcode, DexField* field, Location obj, Location& src_or_dst) { always_assert(is_ifield_op(opcode)); if (is_iget(opcode)) { auto iget = new IRInstruction(opcode); iget->set_field(field); src_or_dst.type = field->get_class(); iget->set_src(0, obj.get_reg()); push_instruction(iget); push_instruction( (new IRInstruction(opcode::move_result_pseudo_for_iget(opcode))) ->set_dest(src_or_dst.get_reg())); } else { auto iput = new IRInstruction(opcode); iput->set_field(field); iput->set_src(0, src_or_dst.get_reg()); iput->set_src(1, obj.get_reg()); push_instruction(iput); } }