/** * Open log */ int log_open(const char *file, const char *ident, int level) { log_close(); lfd = strcasecmp(file, "stderr") ? open(file, O_WRONLY | O_CREAT | O_APPEND, 0600) : STDERR_FILENO; log_ident(ident); log_level(level); return lfd; }
/** * Global code of zcmd handler * @return CMD_RES_xxx */ static int conn_zcmd_first(XS_CONN *conn) { int rc = CMD_RES_NEXT; XS_CMD *cmd = conn->zcmd; // check project if (conn->user == NULL && cmd->cmd != CMD_USE && cmd->cmd != CMD_QUIT && cmd->cmd != CMD_TIMEOUT) { log_warning_conn("project not specified (CMD:%d)", cmd->cmd); return XS_CMD_DONT_ANS(cmd) ? CMD_RES_CONT : CONN_RES_ERR(NOPROJECT); } // parse global command type [first] if (cmd->cmd == CMD_QUIT) rc = CMD_RES_QUIT; else if (cmd->cmd == CMD_DEBUG) { // show debug info for some special usage (this may cause buffer overflow) char buf[4096]; XS_CMDS *cmds; XS_DB *db; int len = 0; // basic info len += sprintf(&buf[len], "id:%s, sock:[%d], name:%s, home:%s, rcv_size:%d, flag:0x%04x\n", log_ident(NULL), CONN_FD(), conn->user->name, conn->user->home, conn->rcv_size, conn->flag); // db list len += sprintf(&buf[len], "DBS:"); for (db = conn->user->db; db != NULL; db = db->next) { len += sprintf(&buf[len], " [%s] ->", db->name); } len += sprintf(&buf[len], " [NULL]\nCMDS:\n"); // cmd list for (cmds = conn->zhead; cmds != NULL && len < (sizeof(buf) - 256); cmds = cmds->next) { len += sprintf(&buf[len], " -> {cmd:%d,arg1:%d,arg2:%d,blen1:%d,blen:%d}\n", cmds->cmd->cmd, cmds->cmd->arg1, cmds->cmd->arg2, cmds->cmd->blen1, cmds->cmd->blen); } if (cmds == NULL) len += sprintf(&buf[len], " -> {NULL}"); else len += sprintf(&buf[len], " -> ..."); rc = CONN_RES_OK3(INFO, buf, len); } else if (cmd->cmd == CMD_TIMEOUT) { // set timeout conn->tv.tv_sec = XS_CMD_ARG(cmd); rc = CONN_RES_OK(TIMEOUT_SET); log_debug_conn("adjust timeout (SEC:%d)", conn->tv.tv_sec); } return rc; }
static OpndLoopInfo processOpnd(LoopNode* loopHead, LoopTree* lt, InstStack& defStack, Opnd* opnd) { OpndLoopInfo result; Inst* defInst = opnd->getInst(); if (Log::isEnabled()) { log_ident(defStack.size()); defInst->print(Log::out()); Log::out()<<"]"<<std::endl; } if (std::find(defStack.begin(), defStack.end(), defInst)!=defStack.end()) { result.setType(OpndLoopInfo::COUNTER); result.setIncrement(0); if (Log::isEnabled()) { log_ident(defStack.size()); Log::out()<<"Found duplicate in def stack -> stopping recursion. ";result.print(Log::out()); Log::out()<<std::endl; } return result; } Node* defNode = defInst->getNode(); Opcode opcode = defInst->getOpcode(); if (opcode == Op_LdConstant) { result.setType(OpndLoopInfo::LD_CONST); result.setConst(defInst->asConstInst()->getValue().i4); if (Log::isEnabled()) { log_ident(defStack.size()); Log::out()<<"assigning to const -> stopping recursion. ";result.print(Log::out());Log::out()<<std::endl; } return result; } if (!loopHead->inLoop(defNode)) { if (Log::isEnabled()) { log_ident(defStack.size()); Log::out()<<"Inst out of the loop -> stopping recursion. ";result.print(Log::out()); Log::out()<<std::endl; } return result; } defStack.push_back(defInst); if (opcode == Op_Phi) { OpndLoopInfo info1 = processOpnd(loopHead, lt, defStack, defInst->getSrc(0)); OpndLoopInfo info2 = processOpnd(loopHead, lt, defStack, defInst->getSrc(1)); if (Log::isEnabled()) { log_ident(defStack.size()); Log::out()<<"PHI(";info1.print(Log::out());Log::out()<<",";info2.print(Log::out());Log::out()<<")"<<std::endl; } if ( ((info1.isCounter() && !info1.isPhiSplit()) && (info2.isDOL() || info2.isLDConst())) || ((info2.isCounter() && !info2.isPhiSplit()) && (info1.isDOL() || info1.isLDConst())) ) { result.setType(OpndLoopInfo::COUNTER); result.setIncrement(info1.isCounter() ? info1.getIncrement() : info2.getIncrement()); result.markPhiSplit(); } else { result.setType(OpndLoopInfo::UNDEF); } } else if (opcode == Op_Add || opcode == Op_Sub) { //todo: LADD Opnd *op1 = defInst->getSrc(0); Opnd *op2 = defInst->getSrc(1); OpndLoopInfo info1 = processOpnd(loopHead, lt, defStack, op1); OpndLoopInfo info2 = processOpnd(loopHead, lt, defStack, op2); if ((info1.isLDConst() || info1.isDOL()) && (info2.isLDConst() || info2.isDOL())) { if (info1.isLDConst() && info2.isLDConst() && info1.getConst() == info2.getConst()) { result.setType(OpndLoopInfo::LD_CONST); result.setConst(info1.getConst()); } else { //result is DOL (default type) } } else if ((info1.isCounter() && info2.isLDConst()) || (info2.isCounter() && info1.isLDConst())) { int increment = info1.isCounter()? info1.getIncrement(): info2.getIncrement(); int diff = info1.isLDConst()? info1.getConst(): info2.getConst(); //we use SSA form to analyze how opnd changes in loop and we do not analyze actual control flow, // so we can unroll loops with monotonically changing 'counters' only. //Example: when 'counter' changes not monotonically and we can't unroll: //idx=0; loop {idx+=100; if(idx>=100) break; idx-=99;} ->'increment'=1 but not monotonicaly. bool monotonousFlag = increment == 0 || diff == 0 || (opcode == Op_Add && signof(diff) == signof(increment)) || (opcode == Op_Sub && signof(diff) != signof(increment)); if (monotonousFlag) { result.setType(OpndLoopInfo::COUNTER); if ((info1.isCounter() && info1.isPhiSplit()) || (info2.isCounter() && info2.isPhiSplit())) { result.markPhiSplit(); } //TO IMPROVE: for loops like: for (; length-1>=0;length--){...} //we have 2 SUBs by -1 => "-2", but real counter is changed by "-1". //Loop unroll will use "-2". It's ok, because this value is used in a guard inst //and ABS(increment_in_unroll) >= ABS(real_increment). This work only for monotonous loops. //To make increment_in_unroll == real_increment we must track modifications (SUB,ADD) that affects vars only. if (opcode == Op_Add) { result.setIncrement(increment + diff); } else { result.setIncrement(increment - diff); } } else { result.setType(OpndLoopInfo::UNDEF); } } else { result.setType(OpndLoopInfo::UNDEF); } } else if (opcode == Op_StVar || opcode == Op_LdVar) { Opnd* newOpnd = defInst->getSrc(0); result = processOpnd(loopHead, lt, defStack, newOpnd); } else if (opcode == Op_TauArrayLen) { Opnd* arrayOpnd = defInst->getSrc(0); result = processOpnd(loopHead, lt, defStack, arrayOpnd); } else { //unsupported op result.setType(OpndLoopInfo::UNDEF); if (Log::isEnabled()) { log_ident(defStack.size()); Log::out()<<"unknown op -> stopping recursion. "; } } defStack.pop_back(); if (Log::isEnabled()) { log_ident(defStack.size()); result.print(Log::out());Log::out()<<std::endl; } return result; }