void create_runtime_exception_block( DexString* except_str, std::vector<IRInstruction*>& block) { // new-instance v0, Ljava/lang/RuntimeException; // type@3852 // const-string v1, "Exception String e.g. Too many args" // string@7a6d // invoke-direct {v0, v1}, Ljava/lang/RuntimeException;.<init>:(Ljava/lang/String;)V // throw v0 auto new_inst = (new IRInstruction(OPCODE_NEW_INSTANCE)) ->set_type(DexType::make_type("Ljava/lang/RuntimeException;")); new_inst->set_dest(0); IRInstruction* const_inst = (new IRInstruction(OPCODE_CONST_STRING))->set_string(except_str); const_inst->set_dest(1); auto ret = DexType::make_type("V"); auto arg = DexType::make_type("Ljava/lang/String;"); auto args = DexTypeList::make_type_list({arg}); auto proto = DexProto::make_proto(ret, args); auto meth = DexMethod::make_method( DexType::make_type("Ljava/lang/RuntimeException;"), DexString::make_string("<init>"), proto); auto invk = new IRInstruction(OPCODE_INVOKE_DIRECT); invk->set_method(meth); invk->set_arg_word_count(2); invk->set_src(0, 0); invk->set_src(1, 1); IRInstruction* throwinst = new IRInstruction(OPCODE_THROW); block.emplace_back(new_inst); block.emplace_back(const_inst); block.emplace_back(invk); block.emplace_back(throwinst); }
IndexScaleDispOpnd::IndexScaleDispOpnd(Opnd index, Opnd scale, Opnd disp, TypeId deref_type ) : AddrExpOpnd(opnd::INDEX_SCALE_DISP, deref_type) { set_src(0, index); set_src(1, scale); set_src(2, disp); }
BaseIndexDispOpnd::BaseIndexDispOpnd(Opnd base, Opnd index, Opnd disp, TypeId deref_type ) : AddrExpOpnd(opnd::BASE_INDEX_DISP, deref_type) { set_src(0, base); set_src(1, index); set_src(2, disp); }
IndexSymDispOpnd::IndexSymDispOpnd(Opnd index, Opnd addr_sym, Opnd disp, TypeId deref_type) : AddrExpOpnd(opnd::INDEX_SYM_DISP, deref_type) { set_src(0, index); set_src(1, addr_sym); set_src(2, disp); }
BaseIndexScaleDispOpnd::BaseIndexScaleDispOpnd(Opnd base, Opnd index, Opnd scale, Opnd disp, TypeId deref_type ) : AddrExpOpnd(opnd::BASE_INDEX_SCALE_DISP, deref_type) { set_src(0, base); set_src(1, index); set_src(2, scale); set_src(3, disp); }
void ICMPv4::ping_reply(full_header* full_hdr, uint16_t size) { auto packet_ptr = inet_.create_packet(size); auto buf = packet_ptr->buffer(); icmp_header* hdr = &reinterpret_cast<full_header*>(buf)->icmp_hdr; hdr->type = ICMP_ECHO_REPLY; hdr->code = 0; hdr->identifier = full_hdr->icmp_hdr.identifier; hdr->sequence = full_hdr->icmp_hdr.sequence; debug("<ICMP> Rest of header IN: 0x%lx OUT: 0x%lx\n", full_hdr->icmp_hdr.rest, hdr->rest); debug("<ICMP> Transmitting answer\n"); // Populate response IP header auto ip4_pckt = static_unique_ptr_cast<PacketIP4>(std::move(packet_ptr)); ip4_pckt->init(); ip4_pckt->set_src(full_hdr->ip_hdr.daddr); ip4_pckt->set_dst(full_hdr->ip_hdr.saddr); ip4_pckt->set_protocol(IP4::IP4_ICMP); ip4_pckt->set_ip_data_length(sizeof(icmp_header) + size - sizeof(full_header)); // Copy payload from old to new packet uint8_t* payload = reinterpret_cast<uint8_t*>(hdr) + sizeof(icmp_header); uint8_t* source = reinterpret_cast<uint8_t*>(&full_hdr->icmp_hdr) + sizeof(icmp_header); memcpy(payload, source, size - sizeof(full_header)); hdr->checksum = 0; hdr->checksum = net::checksum(reinterpret_cast<uint16_t*>(hdr), size - sizeof(full_header) + sizeof(icmp_header)); network_layer_out_(std::move(ip4_pckt)); }
void renumber_registers(IRCode* code, bool width_aware) { auto chains = calculate_ud_chains(code); Rank rank; Parent parent; DefSets def_sets((RankPMap(rank)), (ParentPMap(parent))); for (const auto& mie : InstructionIterable(code)) { if (mie.insn->dests_size()) { def_sets.make_set(mie.insn); } } unify_defs(chains, &def_sets); SymRegMapper sym_reg_mapper(width_aware); for (auto& mie : InstructionIterable(code)) { auto insn = mie.insn; if (insn->dests_size()) { auto sym_reg = sym_reg_mapper.make(def_sets.find_set(insn)); insn->set_dest(sym_reg); } } for (auto& mie : InstructionIterable(code)) { auto insn = mie.insn; for (size_t i = 0; i < insn->srcs_size(); ++i) { auto& defs = chains.at(Use{insn, insn->src(i)}); insn->set_src(i, sym_reg_mapper.at(def_sets.find_set(*defs.begin()))); } } code->set_registers_size(sym_reg_mapper.regs_size()); }
void DexInstruction::verify_encoding() const { auto test = m_count ? new DexInstruction(opcode()) : new DexInstruction(opcode(), 0); if (dests_size()) { test->set_dest(dest()); } for (unsigned i = 0; i < srcs_size(); i++) { test->set_src(i, src(i)); } if (has_range_base()) test->set_range_base(range_base()); if (has_range_size()) test->set_range_size(range_size()); if (has_arg_word_count()) test->set_arg_word_count(arg_word_count()); if (has_literal()) test->set_literal(literal()); if (has_offset()) test->set_offset(offset()); assert_log(m_opcode == test->m_opcode, "%x %x\n", m_opcode, test->m_opcode); for (unsigned i = 0; i < m_count; i++) { assert_log(m_arg[i] == test->m_arg[i], "(%x %x) (%x %x)", m_opcode, m_arg[i], test->m_opcode, test->m_arg[i]); } delete test; }
int string_convert_src(const src_string &src) { set_src(src); int err = string_convert(); finish(); return err; }
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::new_array(DexType* type, const Location& size, const Location& dst) { auto insn = new IRInstruction(OPCODE_NEW_ARRAY); insn->set_type(type); insn->set_arg_word_count(1); insn->set_src(0, size.get_reg()); push_instruction(insn); push_instruction((new IRInstruction(IOPCODE_MOVE_RESULT_PSEUDO_OBJECT)) ->set_dest(dst.get_reg())); }
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); } }
void MethodBlock::invoke(IROpcode opcode, DexMethodRef* meth, const std::vector<Location>& args) { always_assert(is_invoke(opcode)); auto invk = new IRInstruction(opcode); uint16_t arg_count = static_cast<uint16_t>(args.size()); invk->set_method(meth)->set_arg_word_count(arg_count); for (uint16_t i = 0; i < arg_count; i++) { auto arg = args.at(i); invk->set_src(i, arg.get_reg()); } push_instruction(invk); }
void MethodBlock::invoke(DexOpcode opcode, DexMethod* meth, std::vector<Location>& args) { always_assert(is_invoke(opcode)); auto invk = new DexOpcodeMethod(opcode, meth, 0); uint16_t arg_count = static_cast<uint16_t>(args.size()); invk->set_arg_word_count(arg_count); for (uint16_t i = 0; i < arg_count; i++) { auto arg = args[i]; invk->set_src(i, reg_num(arg)); } if (arg_count > mc->out_count) mc->out_count = arg_count; push_instruction(invk); }
void MethodBlock::ret(Location loc) { auto ch = type_shorty(loc.type); assert(ch != 'V'); DexOpcode opcode; if (ch == 'L') opcode = OPCODE_RETURN_OBJECT; else if (ch == 'J' || ch == 'D') opcode = OPCODE_RETURN_WIDE; else opcode = OPCODE_RETURN; auto ret = new DexInstruction(opcode); ret->set_src(0, reg_num(loc)); push_instruction(ret); }
void MethodBlock::sfield_op(DexCodeItemOpcode opcode, DexField* field, Location& src_or_dst) { always_assert(is_sfield_op(opcode)); if (is_sget(opcode)) { auto sget = new DexOpcodeField(opcode, field); sget->set_dest(reg_num(src_or_dst)); src_or_dst.type = field->get_class(); push_opcode(sget); } else { auto sput = new DexOpcodeField(opcode, field); sput->set_src(0, reg_num(src_or_dst)); push_opcode(sput); } }
void UDP::WriteBuffer::write() { // the bytes remaining to be written UDP::Packet_ptr chain_head{}; debug("<UDP> %i bytes to write, need %i packets \n", remaining(), remaining() / udp.max_datagram_size() + (remaining() % udp.max_datagram_size() ? 1 : 0)); do { size_t total = remaining(); total = (total > udp.max_datagram_size()) ? udp.max_datagram_size() : total; // create some packet p (and convert it to PacketUDP) auto p = udp.stack().createPacket(0); // fill buffer (at payload position) memcpy(p->buffer() + PacketUDP::HEADERS_SIZE, buf.get() + this->offset, total); // initialize packet with several infos auto p2 = std::static_pointer_cast<PacketUDP>(p); p2->init(); p2->header().sport = htons(l_port); p2->header().dport = htons(d_port); p2->set_src(l_addr); p2->set_dst(d_addr); p2->set_length(total); // Attach packet to chain if (!chain_head) chain_head = p2; else chain_head->chain(p2); // next position in buffer this->offset += total; } while ( remaining() ); // ship the packet udp.transmit(chain_head); }
MethodBlock* MethodBlock::switch_op(Location test, std::map<int, MethodBlock*>& cases) { auto sw_opcode = new IRInstruction(OPCODE_PACKED_SWITCH); sw_opcode->set_src(0, test.get_reg()); // Convert to SwitchIndices map. std::map<SwitchIndices, MethodBlock*> indices_cases; for (auto it : cases) { SwitchIndices indices = {it.first}; indices_cases[indices] = it.second; } auto mb = make_switch_block(sw_opcode, indices_cases); // Copy initialized case blocks back. for (auto it : indices_cases) { SwitchIndices indices = it.first; always_assert(indices.size()); int idx = *indices.begin(); cases[idx] = it.second; } return mb; }
void ICMPv6::discover() { // ether-broadcast an IPv6 packet to all routers // IPv6mcast_02: 33:33:00:00:00:02 auto pckt = IP6::create( IP6::PROTO_ICMPv6, Ethernet::addr::IPv6mcast_02, IP6::addr::link_unspecified); // RFC4861 4.1. Router Solicitation Message Format pckt->set_hoplimit(255); NDP::router_sol* ndp = (NDP::router_sol*) pckt->payload(); // set to Router Solicitation Request ndp->type = ICMPv6::ND_ROUTER_SOL; ndp->code = 0; ndp->checksum = 0; ndp->reserved = 0; auto icmp = std::static_pointer_cast<PacketICMP6> (pckt); // source and destination addresses icmp->set_src(this->local_ip()); //IP6::addr::link_unspecified); icmp->set_dst(IP6::addr::link_all_routers); // ICMP header length field icmp->set_length(sizeof(NDP::router_sol)); // calculate and set checksum // NOTE: do this after changing packet contents! ndp->checksum = ICMPv6::checksum(icmp); this->transmit(icmp); /// DHCPv6 test /// // ether-broadcast an IPv6 packet to all routers //pckt = IP6::create( // IP6::PROTO_UDP, // Ethernet::addr::IPv6mcast_02, // IP6::addr::link_unspecified); }
void IRInstruction::normalize_registers() { if (is_invoke(opcode())) { auto& args = get_method()->get_proto()->get_args()->get_type_list(); size_t old_srcs_idx{0}; size_t srcs_idx{0}; if (m_opcode != OPCODE_INVOKE_STATIC) { ++srcs_idx; ++old_srcs_idx; } for (size_t args_idx = 0; args_idx < args.size(); ++args_idx) { always_assert_log( old_srcs_idx < srcs_size(), "Invalid arg indices in %s args_idx %d old_srcs_idx %d\n", SHOW(this), args_idx, old_srcs_idx); set_src(srcs_idx++, src(old_srcs_idx)); old_srcs_idx += is_wide_type(args.at(args_idx)) ? 2 : 1; } always_assert(old_srcs_idx == srcs_size()); set_arg_word_count(srcs_idx); } }
void set_src(const src_string &src) { /* PRIVATE: External use can easily cause use-after-free bugs */ set_src(src.c_str(),src.length()); }
int main(int argc,char** argv) { int myrank=0,nprocs=1; int latsize[4],localsize[4]; int netSize[16],netPos[16],netDim; int i,j,t,npIn,nsite; int Niter = QCD_NITER; QCDSpinor* pSrc; QCDSpinor* pDest; QCDMatrix* pGauge; QCDReal Enorm = QCD_ENORM; QCDReal Cks = QCD_CKS; QCDReal* pCorr; double tstart,tend,ttotal; char* pStr; int ItimeS,NtimeS,ics,ids,is,ie,ipet,it,Nconv,cnt; double CorrF,Diff,rr; unsigned long flops; double tt; latsize[0] = 0; latsize[1] = 0; latsize[2] = 0; latsize[3] = 0; netDim = 4; netSize[0] = 0; netSize[1] = 0; netSize[2] = 0; netSize[3] = 0; for(i=1;i<argc;i++){ if(argv[i][0] == 'L'){ t = 0; for(j=1;j<strlen(argv[i]);j++){ if(argv[i][j] == 'x'){ t++; } else if(argv[i][j] >= '0' && argv[i][j] <= '9'){ latsize[t] = 10*latsize[t] + (int)(argv[i][j] - '0'); } } } else if(argv[i][0] == 'P'){ t = 0; for(j=1;j<strlen(argv[i]);j++){ if(argv[i][j] == 'x'){ t++; } else if(argv[i][j] >= '0' && argv[i][j] <= '9'){ netSize[t] = 10*netSize[t] + (int)(argv[i][j] - '0'); } } } } t = 0; for(i=0;i<4;i++){ if(latsize[0] == 0){ t++; } } if(t > 0){ latsize[0] = QCD_NX; latsize[1] = QCD_NY; latsize[2] = QCD_NZ; latsize[3] = QCD_NT; } MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&nprocs); MPI_Comm_rank(MPI_COMM_WORLD,&myrank); npIn = 1; for(i=0;i<4;i++){ npIn *= netSize[i]; //debug /* printf("netSize[%d] == %d\n", i, netSize[i]); */ } if(npIn != nprocs){ if(myrank == 0){ printf("Number of processes is invalid\n"); } return 0; } nsite = 1; for(i=0;i<4;i++){ localsize[i] = latsize[i] / netSize[i]; nsite *= localsize[i]; } t = myrank; for(i=0;i<4;i++){ netPos[i] = t % netSize[i]; t /= netSize[i]; } QCDDopr_Init(localsize[0],localsize[1],localsize[2],localsize[3],netSize[0],netSize[1],netSize[2],netSize[3],myrank); if(myrank == 0){ printf("=============================================\n"); printf("QCD base MPI program\n"); printf(" Lattice size = %dx%dx%dx%d\n",latsize[0],latsize[1],latsize[2],latsize[3]); printf("Decomposed by %d procs : %dx%dx%dx%d\n",nprocs,netSize[0],netSize[1],netSize[2],netSize[3]); printf(" Local Lattice size = %dx%dx%dx%d\n",localsize[0],localsize[1],localsize[2],localsize[3]); printf("\n Cks = %f\n",Cks); printf("=============================================\n"); } //debug /* printf("xxx\n"); */ pGauge = (QCDMatrix*)malloc(sizeof(QCDMatrix) * 4 * nsite + 512); uinit((double*)pGauge,latsize[0],latsize[1],latsize[2],latsize[3]); //debug /* printf("xxx\n"); */ pSrc = (QCDSpinor*)malloc(sizeof(QCDSpinor) * nsite + 128); pDest = (QCDSpinor*)malloc(sizeof(QCDSpinor) * nsite + 128); pCorr = (QCDReal*)malloc(sizeof(QCDReal) * latsize[3]); for(i=0;i<latsize[3];i++){ pCorr[i] = 0.0; } ttotal = 0.0; /* for(ics=0;ics<QCD_NCOL;ics++){ */ /* for(ids=0;ids<QCD_ND;ids++){ */ for(ics=0;ics<1;ics++){ for(ids=0;ids<1;ids++){ set_src(ids,ics,pSrc,0); MPI_Barrier(MPI_COMM_WORLD); tstart = mysecond(); Solve_CG(pDest,pGauge,pSrc,Cks,Enorm,&Nconv,&Diff); MPI_Barrier(MPI_COMM_WORLD); tend = mysecond() - tstart; ttotal += tend; if(myrank == 0){ printf(" %3d %3d %6d %12.4e ... %f sec\n", ics, ids, Nconv, Diff,tend); } for(i=0;i<latsize[3];i++){ ipet = i/localsize[3]; it = i % localsize[3]; if(ipet == netPos[3]){ is = it*localsize[0]*localsize[1]*localsize[2]; QCDLA_Norm(&CorrF,pDest + is,localsize[0]*localsize[1]*localsize[2]); } else{ CorrF = 0.0; } MPI_Allreduce(&CorrF,&rr,1,MPI_DOUBLE_PRECISION,MPI_SUM,MPI_COMM_WORLD); pCorr[i] = pCorr[i] + rr; } } } if(myrank == 0){ printf("\nPs meson correlator:\n"); for(i=0;i<latsize[3];i++){ printf("%d: %0.8E\n",i,pCorr[i]); } printf("\n Avg. Solver Time = %f [sec]\n",ttotal / 12); } MPI_Barrier(MPI_COMM_WORLD); //debug /* printf("finish\n"); */ return 0; }
void BaseIndexScaleDispOpnd::set_disp(Opnd opnd) { set_src(3, opnd); }
MethodBlock* MethodBlock::switch_op(Location test, std::map<int, MethodBlock*>& cases) { auto sw_opcode = new DexInstruction(OPCODE_PACKED_SWITCH); sw_opcode->set_src(0, reg_num(test)); return make_switch_block(sw_opcode, cases); }
void MethodBlock::throwex(Location ex) { auto insn = new IRInstruction(OPCODE_THROW); insn->set_src(0, ex.get_reg()); push_instruction(insn); }
void BaseIndexScaleDispOpnd::set_index(Opnd opnd) { set_src(1, opnd); }
void set_src(const srcT * const src,const size_t len) { set_src(src,src+len); }
MethodBlock* MethodBlock::switch_op( Location test, std::map<SwitchIndices, MethodBlock*>& cases) { auto sw_opcode = new IRInstruction(OPCODE_PACKED_SWITCH); sw_opcode->set_src(0, test.get_reg()); return make_switch_block(sw_opcode, cases); }
void BaseIndexScaleDispOpnd::set_scale(Opnd opnd) { set_src(2, opnd); }
void set_src(const srcT * const src) { // C-string set_src(src,my_strlen(src)); }